summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/audio_in_manager.cpp2
-rw-r--r--src/audio_core/audio_manager.cpp4
-rw-r--r--src/audio_core/audio_out_manager.cpp2
-rw-r--r--src/audio_core/audio_render_manager.cpp2
-rw-r--r--src/audio_core/in/audio_in.cpp2
-rw-r--r--src/audio_core/in/audio_in_system.cpp6
-rw-r--r--src/audio_core/out/audio_out.cpp2
-rw-r--r--src/audio_core/out/audio_out_system.cpp8
-rw-r--r--src/audio_core/renderer/audio_renderer.cpp2
-rw-r--r--src/audio_core/renderer/behavior/info_updater.cpp38
-rw-r--r--src/audio_core/renderer/command/effect/reverb.cpp3
-rw-r--r--src/audio_core/renderer/effect/i3dl2.h3
-rw-r--r--src/audio_core/renderer/effect/reverb.h8
-rw-r--r--src/audio_core/renderer/memory/pool_mapper.cpp2
-rw-r--r--src/audio_core/renderer/system.cpp50
-rw-r--r--src/audio_core/renderer/voice/voice_info.cpp8
-rw-r--r--src/common/CMakeLists.txt13
-rw-r--r--src/common/bit_cast.h20
-rw-r--r--src/common/input.h2
-rw-r--r--src/common/logging/filter.cpp2
-rw-r--r--src/common/logging/types.h202
-rw-r--r--src/common/overflow.h22
-rw-r--r--src/common/scratch_buffer.h1
-rw-r--r--src/common/settings.cpp2
-rw-r--r--src/common/settings.h11
-rw-r--r--src/common/steady_clock.cpp56
-rw-r--r--src/common/steady_clock.h23
-rw-r--r--src/common/wall_clock.cpp39
-rw-r--r--src/common/wall_clock.h3
-rw-r--r--src/common/windows/timer_resolution.cpp109
-rw-r--r--src/common/windows/timer_resolution.h38
-rw-r--r--src/common/x64/native_clock.cpp17
-rw-r--r--src/core/CMakeLists.txt77
-rw-r--r--src/core/constants.cpp27
-rw-r--r--src/core/constants.h2
-rw-r--r--src/core/core.cpp11
-rw-r--r--src/core/core.h5
-rw-r--r--src/core/core_timing.cpp55
-rw-r--r--src/core/core_timing.h6
-rw-r--r--src/core/debugger/debugger.cpp7
-rw-r--r--src/core/debugger/gdbstub.cpp6
-rw-r--r--src/core/hardware_properties.h8
-rw-r--r--src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp21
-rw-r--r--src/core/hle/kernel/init/init_slab_setup.cpp8
-rw-r--r--src/core/hle/kernel/k_address_arbiter.cpp8
-rw-r--r--src/core/hle/kernel/k_address_space_info.cpp79
-rw-r--r--src/core/hle/kernel/k_address_space_info.h2
-rw-r--r--src/core/hle/kernel/k_client_port.cpp1
-rw-r--r--src/core/hle/kernel/k_client_port.h1
-rw-r--r--src/core/hle/kernel/k_client_session.cpp1
-rw-r--r--src/core/hle/kernel/k_condition_variable.cpp50
-rw-r--r--src/core/hle/kernel/k_device_address_space.h4
-rw-r--r--src/core/hle/kernel/k_light_lock.cpp8
-rw-r--r--src/core/hle/kernel/k_port.cpp1
-rw-r--r--src/core/hle/kernel/k_process.cpp10
-rw-r--r--src/core/hle/kernel/k_process.h4
-rw-r--r--src/core/hle/kernel/k_resource_limit.cpp3
-rw-r--r--src/core/hle/kernel/k_scheduler_lock.h11
-rw-r--r--src/core/hle/kernel/k_scoped_lock.h1
-rw-r--r--src/core/hle/kernel/k_server_session.cpp11
-rw-r--r--src/core/hle/kernel/k_server_session.h12
-rw-r--r--src/core/hle/kernel/k_thread.cpp291
-rw-r--r--src/core/hle/kernel/k_thread.h179
-rw-r--r--src/core/hle/kernel/kernel.cpp300
-rw-r--r--src/core/hle/kernel/kernel.h136
-rw-r--r--src/core/hle/kernel/service_thread.cpp206
-rw-r--r--src/core/hle/kernel/service_thread.h29
-rw-r--r--src/core/hle/kernel/svc/svc_info.cpp5
-rw-r--r--src/core/hle/kernel/svc/svc_port.cpp51
-rw-r--r--src/core/hle/kernel/svc/svc_synchronization.cpp45
-rw-r--r--src/core/hle/kernel/svc_types.h1
-rw-r--r--src/core/hle/service/acc/acc.cpp117
-rw-r--r--src/core/hle/service/acc/acc.h41
-rw-r--r--src/core/hle/service/acc/async_context.cpp10
-rw-r--r--src/core/hle/service/acc/async_context.h8
-rw-r--r--src/core/hle/service/acc/errors.h10
-rw-r--r--src/core/hle/service/am/am.cpp281
-rw-r--r--src/core/hle/service/am/am.h197
-rw-r--r--src/core/hle/service/am/applet_ae.cpp82
-rw-r--r--src/core/hle/service/am/applet_ae.h14
-rw-r--r--src/core/hle/service/am/applet_oe.cpp42
-rw-r--r--src/core/hle/service/am/applet_oe.h10
-rw-r--r--src/core/hle/service/am/applets/applet_controller.cpp7
-rw-r--r--src/core/hle/service/am/applets/applet_profile_select.cpp7
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp37
-rw-r--r--src/core/hle/service/aoc/aoc_u.h25
-rw-r--r--src/core/hle/service/apm/apm.cpp20
-rw-r--r--src/core/hle/service/apm/apm.h3
-rw-r--r--src/core/hle/service/apm/apm_interface.cpp20
-rw-r--r--src/core/hle/service/apm/apm_interface.h12
-rw-r--r--src/core/hle/service/audio/audctl.cpp6
-rw-r--r--src/core/hle/service/audio/audctl.h4
-rw-r--r--src/core/hle/service/audio/audin_u.cpp37
-rw-r--r--src/core/hle/service/audio/audin_u.h14
-rw-r--r--src/core/hle/service/audio/audio.cpp21
-rw-r--r--src/core/hle/service/audio/audio.h3
-rw-r--r--src/core/hle/service/audio/audout_u.cpp40
-rw-r--r--src/core/hle/service/audio/audout_u.h8
-rw-r--r--src/core/hle/service/audio/audren_u.cpp77
-rw-r--r--src/core/hle/service/audio/audren_u.h14
-rw-r--r--src/core/hle/service/audio/errors.h24
-rw-r--r--src/core/hle/service/audio/hwopus.cpp22
-rw-r--r--src/core/hle/service/audio/hwopus.h10
-rw-r--r--src/core/hle/service/bcat/bcat_module.cpp74
-rw-r--r--src/core/hle/service/bcat/bcat_module.h9
-rw-r--r--src/core/hle/service/bpc/bpc.cpp11
-rw-r--r--src/core/hle/service/bpc/bpc.h2
-rw-r--r--src/core/hle/service/btdrv/btdrv.cpp14
-rw-r--r--src/core/hle/service/btdrv/btdrv.h3
-rw-r--r--src/core/hle/service/btm/btm.cpp40
-rw-r--r--src/core/hle/service/btm/btm.h2
-rw-r--r--src/core/hle/service/caps/caps.cpp18
-rw-r--r--src/core/hle/service/caps/caps.h3
-rw-r--r--src/core/hle/service/caps/caps_a.h4
-rw-r--r--src/core/hle/service/caps/caps_c.cpp4
-rw-r--r--src/core/hle/service/caps/caps_c.h6
-rw-r--r--src/core/hle/service/caps/caps_su.cpp4
-rw-r--r--src/core/hle/service/caps/caps_su.h6
-rw-r--r--src/core/hle/service/caps/caps_u.cpp8
-rw-r--r--src/core/hle/service/caps/caps_u.h10
-rw-r--r--src/core/hle/service/erpt/erpt.cpp11
-rw-r--r--src/core/hle/service/erpt/erpt.h7
-rw-r--r--src/core/hle/service/es/es.cpp32
-rw-r--r--src/core/hle/service/es/es.h7
-rw-r--r--src/core/hle/service/eupld/eupld.cpp11
-rw-r--r--src/core/hle/service/eupld/eupld.h7
-rw-r--r--src/core/hle/service/fatal/fatal.cpp18
-rw-r--r--src/core/hle/service/fatal/fatal.h8
-rw-r--r--src/core/hle/service/fgm/fgm.cpp18
-rw-r--r--src/core/hle/service/fgm/fgm.h6
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp12
-rw-r--r--src/core/hle/service/filesystem/filesystem.h2
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp108
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.h40
-rw-r--r--src/core/hle/service/friend/errors.h11
-rw-r--r--src/core/hle/service/friend/friend.cpp52
-rw-r--r--src/core/hle/service/friend/friend.h7
-rw-r--r--src/core/hle/service/glue/arp.cpp38
-rw-r--r--src/core/hle/service/glue/arp.h12
-rw-r--r--src/core/hle/service/glue/bgtc.cpp4
-rw-r--r--src/core/hle/service/glue/bgtc.h2
-rw-r--r--src/core/hle/service/glue/errors.h7
-rw-r--r--src/core/hle/service/glue/glue.cpp23
-rw-r--r--src/core/hle/service/glue/glue.h3
-rw-r--r--src/core/hle/service/glue/glue_manager.cpp16
-rw-r--r--src/core/hle/service/glue/glue_manager.h16
-rw-r--r--src/core/hle/service/glue/notif.cpp14
-rw-r--r--src/core/hle/service/glue/notif.h12
-rw-r--r--src/core/hle/service/grc/grc.cpp9
-rw-r--r--src/core/hle/service/grc/grc.h6
-rw-r--r--src/core/hle/service/hid/controllers/console_sixaxis.cpp14
-rw-r--r--src/core/hle/service/hid/controllers/console_sixaxis.h13
-rw-r--r--src/core/hle/service/hid/controllers/palma.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/palma.h2
-rw-r--r--src/core/hle/service/hid/hid.cpp254
-rw-r--r--src/core/hle/service/hid/hid.h233
-rw-r--r--src/core/hle/service/hid/hidbus.cpp30
-rw-r--r--src/core/hle/service/hid/hidbus.h29
-rw-r--r--src/core/hle/service/hid/hidbus/hidbus_base.cpp7
-rw-r--r--src/core/hle/service/hid/hidbus/hidbus_base.h12
-rw-r--r--src/core/hle/service/hid/hidbus/ringcon.cpp13
-rw-r--r--src/core/hle/service/hid/hidbus/ringcon.h3
-rw-r--r--src/core/hle/service/hid/hidbus/starlink.cpp6
-rw-r--r--src/core/hle/service/hid/hidbus/starlink.h3
-rw-r--r--src/core/hle/service/hid/hidbus/stubbed.cpp7
-rw-r--r--src/core/hle/service/hid/hidbus/stubbed.h3
-rw-r--r--src/core/hle/service/hid/irs.cpp46
-rw-r--r--src/core/hle/service/hid/irs.h44
-rw-r--r--src/core/hle/service/hid/irsensor/image_transfer_processor.cpp27
-rw-r--r--src/core/hle/service/hid/irsensor/image_transfer_processor.h12
-rw-r--r--src/core/hle/service/hle_ipc.cpp (renamed from src/core/hle/kernel/hle_ipc.cpp)57
-rw-r--r--src/core/hle/service/hle_ipc.h (renamed from src/core/hle/kernel/hle_ipc.h)124
-rw-r--r--src/core/hle/service/ipc_helpers.h (renamed from src/core/hle/ipc_helpers.h)24
-rw-r--r--src/core/hle/service/jit/jit.cpp24
-rw-r--r--src/core/hle/service/jit/jit.h7
-rw-r--r--src/core/hle/service/kernel_helpers.cpp11
-rw-r--r--src/core/hle/service/kernel_helpers.h1
-rw-r--r--src/core/hle/service/lbl/lbl.cpp60
-rw-r--r--src/core/hle/service/lbl/lbl.h6
-rw-r--r--src/core/hle/service/ldn/ldn.cpp92
-rw-r--r--src/core/hle/service/ldn/ldn.h9
-rw-r--r--src/core/hle/service/ldr/ldr.cpp30
-rw-r--r--src/core/hle/service/ldr/ldr.h7
-rw-r--r--src/core/hle/service/lm/lm.cpp16
-rw-r--r--src/core/hle/service/lm/lm.h3
-rw-r--r--src/core/hle/service/mig/mig.cpp9
-rw-r--r--src/core/hle/service/mig/mig.h6
-rw-r--r--src/core/hle/service/mii/mii.cpp38
-rw-r--r--src/core/hle/service/mii/mii.h6
-rw-r--r--src/core/hle/service/mm/mm_u.cpp26
-rw-r--r--src/core/hle/service/mm/mm_u.h7
-rw-r--r--src/core/hle/service/mnpp/mnpp_app.cpp16
-rw-r--r--src/core/hle/service/mnpp/mnpp_app.h7
-rw-r--r--src/core/hle/service/mutex.cpp43
-rw-r--r--src/core/hle/service/mutex.h31
-rw-r--r--src/core/hle/service/ncm/ncm.cpp13
-rw-r--r--src/core/hle/service/ncm/ncm.h6
-rw-r--r--src/core/hle/service/nfc/mifare_user.cpp30
-rw-r--r--src/core/hle/service/nfc/mifare_user.h28
-rw-r--r--src/core/hle/service/nfc/nfc.cpp25
-rw-r--r--src/core/hle/service/nfc/nfc.h6
-rw-r--r--src/core/hle/service/nfc/nfc_device.cpp2
-rw-r--r--src/core/hle/service/nfc/nfc_user.cpp30
-rw-r--r--src/core/hle/service/nfc/nfc_user.h28
-rw-r--r--src/core/hle/service/nfp/nfp.cpp12
-rw-r--r--src/core/hle/service/nfp/nfp.h2
-rw-r--r--src/core/hle/service/nfp/nfp_device.cpp2
-rw-r--r--src/core/hle/service/nfp/nfp_user.cpp52
-rw-r--r--src/core/hle/service/nfp/nfp_user.h50
-rw-r--r--src/core/hle/service/ngct/ngct.cpp14
-rw-r--r--src/core/hle/service/ngct/ngct.h7
-rw-r--r--src/core/hle/service/nifm/nifm.cpp59
-rw-r--r--src/core/hle/service/nifm/nifm.h31
-rw-r--r--src/core/hle/service/nim/nim.cpp43
-rw-r--r--src/core/hle/service/nim/nim.h6
-rw-r--r--src/core/hle/service/npns/npns.cpp11
-rw-r--r--src/core/hle/service/npns/npns.h6
-rw-r--r--src/core/hle/service/ns/errors.h5
-rw-r--r--src/core/hle/service/ns/iplatform_service_manager.cpp14
-rw-r--r--src/core/hle/service/ns/iplatform_service_manager.h12
-rw-r--r--src/core/hle/service/ns/ns.cpp61
-rw-r--r--src/core/hle/service/ns/ns.h17
-rw-r--r--src/core/hle/service/ns/pdm_qry.cpp4
-rw-r--r--src/core/hle/service/ns/pdm_qry.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.h4
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp27
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h12
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.cpp28
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.h26
-rw-r--r--src/core/hle/service/nvdrv/nvmemp.cpp4
-rw-r--r--src/core/hle/service/nvdrv/nvmemp.h4
-rw-r--r--src/core/hle/service/nvnflinger/binder.h (renamed from src/core/hle/service/nvflinger/binder.h)8
-rw-r--r--src/core/hle/service/nvnflinger/buffer_item.h (renamed from src/core/hle/service/nvflinger/buffer_item.h)4
-rw-r--r--src/core/hle/service/nvnflinger/buffer_item_consumer.cpp (renamed from src/core/hle/service/nvflinger/buffer_item_consumer.cpp)12
-rw-r--r--src/core/hle/service/nvnflinger/buffer_item_consumer.h (renamed from src/core/hle/service/nvflinger/buffer_item_consumer.h)4
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp (renamed from src/core/hle/service/nvflinger/buffer_queue_consumer.cpp)40
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_consumer.h (renamed from src/core/hle/service/nvflinger/buffer_queue_consumer.h)4
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_core.cpp (renamed from src/core/hle/service/nvflinger/buffer_queue_core.cpp)4
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_core.h (renamed from src/core/hle/service/nvflinger/buffer_queue_core.h)10
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_defs.h (renamed from src/core/hle/service/nvflinger/buffer_queue_defs.h)2
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_producer.cpp (renamed from src/core/hle/service/nvflinger/buffer_queue_producer.cpp)140
-rw-r--r--src/core/hle/service/nvnflinger/buffer_queue_producer.h (renamed from src/core/hle/service/nvflinger/buffer_queue_producer.h)16
-rw-r--r--src/core/hle/service/nvnflinger/buffer_slot.h (renamed from src/core/hle/service/nvflinger/buffer_slot.h)2
-rw-r--r--src/core/hle/service/nvnflinger/buffer_transform_flags.h (renamed from src/core/hle/service/nvflinger/buffer_transform_flags.h)0
-rw-r--r--src/core/hle/service/nvnflinger/consumer_base.cpp (renamed from src/core/hle/service/nvflinger/consumer_base.cpp)24
-rw-r--r--src/core/hle/service/nvnflinger/consumer_base.h (renamed from src/core/hle/service/nvflinger/consumer_base.h)6
-rw-r--r--src/core/hle/service/nvnflinger/consumer_listener.h (renamed from src/core/hle/service/nvflinger/consumer_listener.h)0
-rw-r--r--src/core/hle/service/nvnflinger/graphic_buffer_producer.cpp (renamed from src/core/hle/service/nvflinger/graphic_buffer_producer.cpp)4
-rw-r--r--src/core/hle/service/nvnflinger/graphic_buffer_producer.h (renamed from src/core/hle/service/nvflinger/graphic_buffer_producer.h)4
-rw-r--r--src/core/hle/service/nvnflinger/hos_binder_driver_server.cpp (renamed from src/core/hle/service/nvflinger/hos_binder_driver_server.cpp)6
-rw-r--r--src/core/hle/service/nvnflinger/hos_binder_driver_server.h (renamed from src/core/hle/service/nvflinger/hos_binder_driver_server.h)6
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.cpp (renamed from src/core/hle/service/nvflinger/nvflinger.cpp)58
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.h (renamed from src/core/hle/service/nvflinger/nvflinger.h)10
-rw-r--r--src/core/hle/service/nvnflinger/parcel.h (renamed from src/core/hle/service/nvflinger/parcel.h)0
-rw-r--r--src/core/hle/service/nvnflinger/pixel_format.h (renamed from src/core/hle/service/nvflinger/pixel_format.h)0
-rw-r--r--src/core/hle/service/nvnflinger/producer_listener.h (renamed from src/core/hle/service/nvflinger/producer_listener.h)0
-rw-r--r--src/core/hle/service/nvnflinger/status.h (renamed from src/core/hle/service/nvflinger/status.h)0
-rw-r--r--src/core/hle/service/nvnflinger/ui/fence.h (renamed from src/core/hle/service/nvflinger/ui/fence.h)0
-rw-r--r--src/core/hle/service/nvnflinger/ui/graphic_buffer.h (renamed from src/core/hle/service/nvflinger/ui/graphic_buffer.h)2
-rw-r--r--src/core/hle/service/nvnflinger/window.h (renamed from src/core/hle/service/nvflinger/window.h)0
-rw-r--r--src/core/hle/service/olsc/olsc.cpp17
-rw-r--r--src/core/hle/service/olsc/olsc.h7
-rw-r--r--src/core/hle/service/pcie/pcie.cpp9
-rw-r--r--src/core/hle/service/pcie/pcie.h6
-rw-r--r--src/core/hle/service/pctl/pctl_module.cpp54
-rw-r--r--src/core/hle/service/pctl/pctl_module.h7
-rw-r--r--src/core/hle/service/pcv/pcv.cpp23
-rw-r--r--src/core/hle/service/pcv/pcv.h6
-rw-r--r--src/core/hle/service/pm/pm.cpp36
-rw-r--r--src/core/hle/service/pm/pm.h3
-rw-r--r--src/core/hle/service/prepo/prepo.cpp37
-rw-r--r--src/core/hle/service/prepo/prepo.h6
-rw-r--r--src/core/hle/service/psc/psc.cpp29
-rw-r--r--src/core/hle/service/psc/psc.h2
-rw-r--r--src/core/hle/service/ptm/psm.cpp18
-rw-r--r--src/core/hle/service/ptm/psm.h6
-rw-r--r--src/core/hle/service/ptm/ptm.cpp10
-rw-r--r--src/core/hle/service/ptm/ptm.h6
-rw-r--r--src/core/hle/service/ptm/ts.cpp6
-rw-r--r--src/core/hle/service/ptm/ts.h4
-rw-r--r--src/core/hle/service/server_manager.cpp448
-rw-r--r--src/core/hle/service/server_manager.h90
-rw-r--r--src/core/hle/service/service.cpp173
-rw-r--r--src/core/hle/service/service.h49
-rw-r--r--src/core/hle/service/set/set.cpp34
-rw-r--r--src/core/hle/service/set/set.h22
-rw-r--r--src/core/hle/service/set/set_sys.cpp18
-rw-r--r--src/core/hle/service/set/set_sys.h14
-rw-r--r--src/core/hle/service/set/settings.cpp15
-rw-r--r--src/core/hle/service/set/settings.h7
-rw-r--r--src/core/hle/service/sm/sm.cpp106
-rw-r--r--src/core/hle/service/sm/sm.h35
-rw-r--r--src/core/hle/service/sm/sm_controller.cpp17
-rw-r--r--src/core/hle/service/sm/sm_controller.h8
-rw-r--r--src/core/hle/service/sockets/bsd.cpp69
-rw-r--r--src/core/hle/service/sockets/bsd.h64
-rw-r--r--src/core/hle/service/sockets/sfdnsres.cpp8
-rw-r--r--src/core/hle/service/sockets/sfdnsres.h4
-rw-r--r--src/core/hle/service/sockets/sockets.cpp19
-rw-r--r--src/core/hle/service/sockets/sockets.h7
-rw-r--r--src/core/hle/service/spl/spl_module.cpp36
-rw-r--r--src/core/hle/service/spl/spl_module.h17
-rw-r--r--src/core/hle/service/ssl/ssl.cpp97
-rw-r--r--src/core/hle/service/ssl/ssl.h7
-rw-r--r--src/core/hle/service/time/time.cpp49
-rw-r--r--src/core/hle/service/time/time.h27
-rw-r--r--src/core/hle/service/time/time_zone_service.cpp14
-rw-r--r--src/core/hle/service/time/time_zone_service.h12
-rw-r--r--src/core/hle/service/usb/usb.cpp79
-rw-r--r--src/core/hle/service/usb/usb.h6
-rw-r--r--src/core/hle/service/vi/display/vi_display.cpp12
-rw-r--r--src/core/hle/service/vi/display/vi_display.h8
-rw-r--r--src/core/hle/service/vi/vi.cpp118
-rw-r--r--src/core/hle/service/vi/vi.h24
-rw-r--r--src/core/hle/service/vi/vi_m.cpp6
-rw-r--r--src/core/hle/service/vi/vi_m.h20
-rw-r--r--src/core/hle/service/vi/vi_s.cpp6
-rw-r--r--src/core/hle/service/vi/vi_s.h20
-rw-r--r--src/core/hle/service/vi/vi_u.cpp6
-rw-r--r--src/core/hle/service/vi/vi_u.h20
-rw-r--r--src/core/memory/cheat_engine.cpp9
-rw-r--r--src/core/reporter.cpp6
-rw-r--r--src/core/reporter.h6
-rw-r--r--src/input_common/CMakeLists.txt2
-rw-r--r--src/input_common/drivers/joycon.cpp4
-rw-r--r--src/input_common/drivers/mouse.cpp27
-rw-r--r--src/input_common/drivers/virtual_amiibo.h2
-rw-r--r--src/input_common/helpers/joycon_driver.cpp2
-rw-r--r--src/input_common/helpers/joycon_driver.h2
-rw-r--r--src/input_common/helpers/joycon_protocol/joycon_types.h14
-rw-r--r--src/input_common/helpers/joycon_protocol/poller.cpp107
-rw-r--r--src/input_common/helpers/joycon_protocol/poller.h15
-rw-r--r--src/input_common/input_mapping.cpp1
-rw-r--r--src/network/CMakeLists.txt2
-rw-r--r--src/video_core/CMakeLists.txt4
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h53
-rw-r--r--src/video_core/engines/maxwell_dma.cpp107
-rw-r--r--src/video_core/engines/maxwell_dma.h88
-rw-r--r--src/video_core/framebuffer_config.h4
-rw-r--r--src/video_core/gpu.cpp2
-rw-r--r--src/video_core/renderer_null/null_rasterizer.h8
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h10
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp30
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp236
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h11
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp32
-rw-r--r--src/video_core/texture_cache/image_base.h3
-rw-r--r--src/video_core/texture_cache/image_info.cpp45
-rw-r--r--src/video_core/texture_cache/image_info.h2
-rw-r--r--src/video_core/texture_cache/texture_cache.h139
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h21
-rw-r--r--src/video_core/texture_cache/types.h1
-rw-r--r--src/video_core/texture_cache/util.cpp98
-rw-r--r--src/video_core/texture_cache/util.h10
-rw-r--r--src/video_core/textures/astc.cpp4
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp1
-rw-r--r--src/yuzu/CMakeLists.txt2
-rw-r--r--src/yuzu/configuration/config.cpp2
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.cpp7
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.h1
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.ui10
-rw-r--r--src/yuzu/main.cpp9
-rw-r--r--src/yuzu_cmd/config.cpp1
-rw-r--r--src/yuzu_cmd/default_ini.h4
-rw-r--r--src/yuzu_cmd/yuzu.cpp4
366 files changed, 5878 insertions, 4171 deletions
diff --git a/src/audio_core/audio_in_manager.cpp b/src/audio_core/audio_in_manager.cpp
index f39fb4002..3dfb613cb 100644
--- a/src/audio_core/audio_in_manager.cpp
+++ b/src/audio_core/audio_in_manager.cpp
@@ -20,7 +20,7 @@ Manager::Manager(Core::System& system_) : system{system_} {
20Result Manager::AcquireSessionId(size_t& session_id) { 20Result Manager::AcquireSessionId(size_t& session_id) {
21 if (num_free_sessions == 0) { 21 if (num_free_sessions == 0) {
22 LOG_ERROR(Service_Audio, "All 4 AudioIn sessions are in use, cannot create any more"); 22 LOG_ERROR(Service_Audio, "All 4 AudioIn sessions are in use, cannot create any more");
23 return Service::Audio::ERR_MAXIMUM_SESSIONS_REACHED; 23 return Service::Audio::ResultOutOfSessions;
24 } 24 }
25 session_id = session_ids[next_session_id]; 25 session_id = session_ids[next_session_id];
26 next_session_id = (next_session_id + 1) % MaxInSessions; 26 next_session_id = (next_session_id + 1) % MaxInSessions;
diff --git a/src/audio_core/audio_manager.cpp b/src/audio_core/audio_manager.cpp
index 2acde668e..10b56f214 100644
--- a/src/audio_core/audio_manager.cpp
+++ b/src/audio_core/audio_manager.cpp
@@ -19,7 +19,7 @@ void AudioManager::Shutdown() {
19 19
20Result AudioManager::SetOutManager(BufferEventFunc buffer_func) { 20Result AudioManager::SetOutManager(BufferEventFunc buffer_func) {
21 if (!running) { 21 if (!running) {
22 return Service::Audio::ERR_OPERATION_FAILED; 22 return Service::Audio::ResultOperationFailed;
23 } 23 }
24 24
25 std::scoped_lock l{lock}; 25 std::scoped_lock l{lock};
@@ -35,7 +35,7 @@ Result AudioManager::SetOutManager(BufferEventFunc buffer_func) {
35 35
36Result AudioManager::SetInManager(BufferEventFunc buffer_func) { 36Result AudioManager::SetInManager(BufferEventFunc buffer_func) {
37 if (!running) { 37 if (!running) {
38 return Service::Audio::ERR_OPERATION_FAILED; 38 return Service::Audio::ResultOperationFailed;
39 } 39 }
40 40
41 std::scoped_lock l{lock}; 41 std::scoped_lock l{lock};
diff --git a/src/audio_core/audio_out_manager.cpp b/src/audio_core/audio_out_manager.cpp
index 1766efde1..f22821360 100644
--- a/src/audio_core/audio_out_manager.cpp
+++ b/src/audio_core/audio_out_manager.cpp
@@ -19,7 +19,7 @@ Manager::Manager(Core::System& system_) : system{system_} {
19Result Manager::AcquireSessionId(size_t& session_id) { 19Result Manager::AcquireSessionId(size_t& session_id) {
20 if (num_free_sessions == 0) { 20 if (num_free_sessions == 0) {
21 LOG_ERROR(Service_Audio, "All 12 Audio Out sessions are in use, cannot create any more"); 21 LOG_ERROR(Service_Audio, "All 12 Audio Out sessions are in use, cannot create any more");
22 return Service::Audio::ERR_MAXIMUM_SESSIONS_REACHED; 22 return Service::Audio::ResultOutOfSessions;
23 } 23 }
24 session_id = session_ids[next_session_id]; 24 session_id = session_ids[next_session_id];
25 next_session_id = (next_session_id + 1) % MaxOutSessions; 25 next_session_id = (next_session_id + 1) % MaxOutSessions;
diff --git a/src/audio_core/audio_render_manager.cpp b/src/audio_core/audio_render_manager.cpp
index 7aba2b423..320715727 100644
--- a/src/audio_core/audio_render_manager.cpp
+++ b/src/audio_core/audio_render_manager.cpp
@@ -28,7 +28,7 @@ SystemManager& Manager::GetSystemManager() {
28Result Manager::GetWorkBufferSize(const AudioRendererParameterInternal& params, 28Result Manager::GetWorkBufferSize(const AudioRendererParameterInternal& params,
29 u64& out_count) const { 29 u64& out_count) const {
30 if (!CheckValidRevision(params.revision)) { 30 if (!CheckValidRevision(params.revision)) {
31 return Service::Audio::ERR_INVALID_REVISION; 31 return Service::Audio::ResultInvalidRevision;
32 } 32 }
33 33
34 out_count = System::GetWorkBufferSize(params); 34 out_count = System::GetWorkBufferSize(params);
diff --git a/src/audio_core/in/audio_in.cpp b/src/audio_core/in/audio_in.cpp
index 91ccd5ad7..df8c44d1f 100644
--- a/src/audio_core/in/audio_in.cpp
+++ b/src/audio_core/in/audio_in.cpp
@@ -46,7 +46,7 @@ Result In::AppendBuffer(const AudioInBuffer& buffer, u64 tag) {
46 if (system.AppendBuffer(buffer, tag)) { 46 if (system.AppendBuffer(buffer, tag)) {
47 return ResultSuccess; 47 return ResultSuccess;
48 } 48 }
49 return Service::Audio::ERR_BUFFER_COUNT_EXCEEDED; 49 return Service::Audio::ResultBufferCountReached;
50} 50}
51 51
52void In::ReleaseAndRegisterBuffers() { 52void In::ReleaseAndRegisterBuffers() {
diff --git a/src/audio_core/in/audio_in_system.cpp b/src/audio_core/in/audio_in_system.cpp
index 934ef8c1c..e23e51758 100644
--- a/src/audio_core/in/audio_in_system.cpp
+++ b/src/audio_core/in/audio_in_system.cpp
@@ -45,11 +45,11 @@ Result System::IsConfigValid(const std::string_view device_name,
45 const AudioInParameter& in_params) const { 45 const AudioInParameter& in_params) const {
46 if ((device_name.size() > 0) && 46 if ((device_name.size() > 0) &&
47 (device_name != GetDefaultDeviceName() && device_name != GetDefaultUacDeviceName())) { 47 (device_name != GetDefaultDeviceName() && device_name != GetDefaultUacDeviceName())) {
48 return Service::Audio::ERR_INVALID_DEVICE_NAME; 48 return Service::Audio::ResultNotFound;
49 } 49 }
50 50
51 if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) { 51 if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) {
52 return Service::Audio::ERR_INVALID_SAMPLE_RATE; 52 return Service::Audio::ResultInvalidSampleRate;
53 } 53 }
54 54
55 return ResultSuccess; 55 return ResultSuccess;
@@ -80,7 +80,7 @@ Result System::Initialize(std::string device_name, const AudioInParameter& in_pa
80 80
81Result System::Start() { 81Result System::Start() {
82 if (state != State::Stopped) { 82 if (state != State::Stopped) {
83 return Service::Audio::ERR_OPERATION_FAILED; 83 return Service::Audio::ResultOperationFailed;
84 } 84 }
85 85
86 session->Initialize(name, sample_format, channel_count, session_id, handle, 86 session->Initialize(name, sample_format, channel_count, session_id, handle,
diff --git a/src/audio_core/out/audio_out.cpp b/src/audio_core/out/audio_out.cpp
index d3ee4f0eb..b7ea13405 100644
--- a/src/audio_core/out/audio_out.cpp
+++ b/src/audio_core/out/audio_out.cpp
@@ -46,7 +46,7 @@ Result Out::AppendBuffer(const AudioOutBuffer& buffer, const u64 tag) {
46 if (system.AppendBuffer(buffer, tag)) { 46 if (system.AppendBuffer(buffer, tag)) {
47 return ResultSuccess; 47 return ResultSuccess;
48 } 48 }
49 return Service::Audio::ERR_BUFFER_COUNT_EXCEEDED; 49 return Service::Audio::ResultBufferCountReached;
50} 50}
51 51
52void Out::ReleaseAndRegisterBuffers() { 52void Out::ReleaseAndRegisterBuffers() {
diff --git a/src/audio_core/out/audio_out_system.cpp b/src/audio_core/out/audio_out_system.cpp
index e096a1dac..bd13f7219 100644
--- a/src/audio_core/out/audio_out_system.cpp
+++ b/src/audio_core/out/audio_out_system.cpp
@@ -33,11 +33,11 @@ std::string_view System::GetDefaultOutputDeviceName() const {
33Result System::IsConfigValid(std::string_view device_name, 33Result System::IsConfigValid(std::string_view device_name,
34 const AudioOutParameter& in_params) const { 34 const AudioOutParameter& in_params) const {
35 if ((device_name.size() > 0) && (device_name != GetDefaultOutputDeviceName())) { 35 if ((device_name.size() > 0) && (device_name != GetDefaultOutputDeviceName())) {
36 return Service::Audio::ERR_INVALID_DEVICE_NAME; 36 return Service::Audio::ResultNotFound;
37 } 37 }
38 38
39 if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) { 39 if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) {
40 return Service::Audio::ERR_INVALID_SAMPLE_RATE; 40 return Service::Audio::ResultInvalidSampleRate;
41 } 41 }
42 42
43 if (in_params.channel_count == 0 || in_params.channel_count == 2 || 43 if (in_params.channel_count == 0 || in_params.channel_count == 2 ||
@@ -45,7 +45,7 @@ Result System::IsConfigValid(std::string_view device_name,
45 return ResultSuccess; 45 return ResultSuccess;
46 } 46 }
47 47
48 return Service::Audio::ERR_INVALID_CHANNEL_COUNT; 48 return Service::Audio::ResultInvalidChannelCount;
49} 49}
50 50
51Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle_, 51Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle_,
@@ -80,7 +80,7 @@ size_t System::GetSessionId() const {
80 80
81Result System::Start() { 81Result System::Start() {
82 if (state != State::Stopped) { 82 if (state != State::Stopped) {
83 return Service::Audio::ERR_OPERATION_FAILED; 83 return Service::Audio::ResultOperationFailed;
84 } 84 }
85 85
86 session->Initialize(name, sample_format, channel_count, session_id, handle, 86 session->Initialize(name, sample_format, channel_count, session_id, handle,
diff --git a/src/audio_core/renderer/audio_renderer.cpp b/src/audio_core/renderer/audio_renderer.cpp
index 51aa17599..a8257eb2e 100644
--- a/src/audio_core/renderer/audio_renderer.cpp
+++ b/src/audio_core/renderer/audio_renderer.cpp
@@ -22,7 +22,7 @@ Result Renderer::Initialize(const AudioRendererParameterInternal& params,
22 if (!manager.AddSystem(system)) { 22 if (!manager.AddSystem(system)) {
23 LOG_ERROR(Service_Audio, 23 LOG_ERROR(Service_Audio,
24 "Both Audio Render sessions are in use, cannot create any more"); 24 "Both Audio Render sessions are in use, cannot create any more");
25 return Service::Audio::ERR_MAXIMUM_SESSIONS_REACHED; 25 return Service::Audio::ResultOutOfSessions;
26 } 26 }
27 system_registered = true; 27 system_registered = true;
28 } 28 }
diff --git a/src/audio_core/renderer/behavior/info_updater.cpp b/src/audio_core/renderer/behavior/info_updater.cpp
index 574cf0982..e312eb166 100644
--- a/src/audio_core/renderer/behavior/info_updater.cpp
+++ b/src/audio_core/renderer/behavior/info_updater.cpp
@@ -48,7 +48,7 @@ Result InfoUpdater::UpdateVoiceChannelResources(VoiceContext& voice_context) {
48 LOG_ERROR(Service_Audio, 48 LOG_ERROR(Service_Audio,
49 "Consumed an incorrect voice resource size, header size={}, consumed={}", 49 "Consumed an incorrect voice resource size, header size={}, consumed={}",
50 in_header->voice_resources_size, consumed_input_size); 50 in_header->voice_resources_size, consumed_input_size);
51 return Service::Audio::ERR_INVALID_UPDATE_DATA; 51 return Service::Audio::ResultInvalidUpdateInfo;
52 } 52 }
53 53
54 input += consumed_input_size; 54 input += consumed_input_size;
@@ -123,7 +123,7 @@ Result InfoUpdater::UpdateVoices(VoiceContext& voice_context,
123 if (consumed_input_size != in_header->voices_size) { 123 if (consumed_input_size != in_header->voices_size) {
124 LOG_ERROR(Service_Audio, "Consumed an incorrect voices size, header size={}, consumed={}", 124 LOG_ERROR(Service_Audio, "Consumed an incorrect voices size, header size={}, consumed={}",
125 in_header->voices_size, consumed_input_size); 125 in_header->voices_size, consumed_input_size);
126 return Service::Audio::ERR_INVALID_UPDATE_DATA; 126 return Service::Audio::ResultInvalidUpdateInfo;
127 } 127 }
128 128
129 out_header->voices_size = consumed_output_size; 129 out_header->voices_size = consumed_output_size;
@@ -184,7 +184,7 @@ Result InfoUpdater::UpdateEffectsVersion1(EffectContext& effect_context, const b
184 if (consumed_input_size != in_header->effects_size) { 184 if (consumed_input_size != in_header->effects_size) {
185 LOG_ERROR(Service_Audio, "Consumed an incorrect effects size, header size={}, consumed={}", 185 LOG_ERROR(Service_Audio, "Consumed an incorrect effects size, header size={}, consumed={}",
186 in_header->effects_size, consumed_input_size); 186 in_header->effects_size, consumed_input_size);
187 return Service::Audio::ERR_INVALID_UPDATE_DATA; 187 return Service::Audio::ResultInvalidUpdateInfo;
188 } 188 }
189 189
190 out_header->effects_size = consumed_output_size; 190 out_header->effects_size = consumed_output_size;
@@ -239,7 +239,7 @@ Result InfoUpdater::UpdateEffectsVersion2(EffectContext& effect_context, const b
239 if (consumed_input_size != in_header->effects_size) { 239 if (consumed_input_size != in_header->effects_size) {
240 LOG_ERROR(Service_Audio, "Consumed an incorrect effects size, header size={}, consumed={}", 240 LOG_ERROR(Service_Audio, "Consumed an incorrect effects size, header size={}, consumed={}",
241 in_header->effects_size, consumed_input_size); 241 in_header->effects_size, consumed_input_size);
242 return Service::Audio::ERR_INVALID_UPDATE_DATA; 242 return Service::Audio::ResultInvalidUpdateInfo;
243 } 243 }
244 244
245 out_header->effects_size = consumed_output_size; 245 out_header->effects_size = consumed_output_size;
@@ -267,7 +267,7 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co
267 } 267 }
268 268
269 if (mix_buffer_count == 0) { 269 if (mix_buffer_count == 0) {
270 return Service::Audio::ERR_INVALID_UPDATE_DATA; 270 return Service::Audio::ResultInvalidUpdateInfo;
271 } 271 }
272 272
273 std::span<const MixInfo::InParameter> in_params{ 273 std::span<const MixInfo::InParameter> in_params{
@@ -281,13 +281,13 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co
281 total_buffer_count += params.buffer_count; 281 total_buffer_count += params.buffer_count;
282 if (params.dest_mix_id > static_cast<s32>(mix_context.GetCount()) && 282 if (params.dest_mix_id > static_cast<s32>(mix_context.GetCount()) &&
283 params.dest_mix_id != UnusedMixId && params.mix_id != FinalMixId) { 283 params.dest_mix_id != UnusedMixId && params.mix_id != FinalMixId) {
284 return Service::Audio::ERR_INVALID_UPDATE_DATA; 284 return Service::Audio::ResultInvalidUpdateInfo;
285 } 285 }
286 } 286 }
287 } 287 }
288 288
289 if (total_buffer_count > mix_buffer_count) { 289 if (total_buffer_count > mix_buffer_count) {
290 return Service::Audio::ERR_INVALID_UPDATE_DATA; 290 return Service::Audio::ResultInvalidUpdateInfo;
291 } 291 }
292 292
293 bool mix_dirty{false}; 293 bool mix_dirty{false};
@@ -317,7 +317,7 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co
317 if (mix_dirty) { 317 if (mix_dirty) {
318 if (behaviour.IsSplitterSupported() && splitter_context.UsingSplitter()) { 318 if (behaviour.IsSplitterSupported() && splitter_context.UsingSplitter()) {
319 if (!mix_context.TSortInfo(splitter_context)) { 319 if (!mix_context.TSortInfo(splitter_context)) {
320 return Service::Audio::ERR_INVALID_UPDATE_DATA; 320 return Service::Audio::ResultInvalidUpdateInfo;
321 } 321 }
322 } else { 322 } else {
323 mix_context.SortInfo(); 323 mix_context.SortInfo();
@@ -327,7 +327,7 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co
327 if (consumed_input_size != in_header->mix_size) { 327 if (consumed_input_size != in_header->mix_size) {
328 LOG_ERROR(Service_Audio, "Consumed an incorrect mixes size, header size={}, consumed={}", 328 LOG_ERROR(Service_Audio, "Consumed an incorrect mixes size, header size={}, consumed={}",
329 in_header->mix_size, consumed_input_size); 329 in_header->mix_size, consumed_input_size);
330 return Service::Audio::ERR_INVALID_UPDATE_DATA; 330 return Service::Audio::ResultInvalidUpdateInfo;
331 } 331 }
332 332
333 input += mix_count * sizeof(MixInfo::InParameter); 333 input += mix_count * sizeof(MixInfo::InParameter);
@@ -384,7 +384,7 @@ Result InfoUpdater::UpdateSinks(SinkContext& sink_context, std::span<MemoryPoolI
384 if (consumed_input_size != in_header->sinks_size) { 384 if (consumed_input_size != in_header->sinks_size) {
385 LOG_ERROR(Service_Audio, "Consumed an incorrect sinks size, header size={}, consumed={}", 385 LOG_ERROR(Service_Audio, "Consumed an incorrect sinks size, header size={}, consumed={}",
386 in_header->sinks_size, consumed_input_size); 386 in_header->sinks_size, consumed_input_size);
387 return Service::Audio::ERR_INVALID_UPDATE_DATA; 387 return Service::Audio::ResultInvalidUpdateInfo;
388 } 388 }
389 389
390 input += consumed_input_size; 390 input += consumed_input_size;
@@ -411,7 +411,7 @@ Result InfoUpdater::UpdateMemoryPools(std::span<MemoryPoolInfo> memory_pools,
411 state != MemoryPoolInfo::ResultState::MapFailed && 411 state != MemoryPoolInfo::ResultState::MapFailed &&
412 state != MemoryPoolInfo::ResultState::InUse) { 412 state != MemoryPoolInfo::ResultState::InUse) {
413 LOG_WARNING(Service_Audio, "Invalid ResultState from updating memory pools"); 413 LOG_WARNING(Service_Audio, "Invalid ResultState from updating memory pools");
414 return Service::Audio::ERR_INVALID_UPDATE_DATA; 414 return Service::Audio::ResultInvalidUpdateInfo;
415 } 415 }
416 } 416 }
417 417
@@ -423,7 +423,7 @@ Result InfoUpdater::UpdateMemoryPools(std::span<MemoryPoolInfo> memory_pools,
423 LOG_ERROR(Service_Audio, 423 LOG_ERROR(Service_Audio,
424 "Consumed an incorrect memory pool size, header size={}, consumed={}", 424 "Consumed an incorrect memory pool size, header size={}, consumed={}",
425 in_header->memory_pool_size, consumed_input_size); 425 in_header->memory_pool_size, consumed_input_size);
426 return Service::Audio::ERR_INVALID_UPDATE_DATA; 426 return Service::Audio::ResultInvalidUpdateInfo;
427 } 427 }
428 428
429 input += consumed_input_size; 429 input += consumed_input_size;
@@ -453,7 +453,7 @@ Result InfoUpdater::UpdatePerformanceBuffer(std::span<u8> performance_output,
453 LOG_ERROR(Service_Audio, 453 LOG_ERROR(Service_Audio,
454 "Consumed an incorrect performance size, header size={}, consumed={}", 454 "Consumed an incorrect performance size, header size={}, consumed={}",
455 in_header->performance_buffer_size, consumed_input_size); 455 in_header->performance_buffer_size, consumed_input_size);
456 return Service::Audio::ERR_INVALID_UPDATE_DATA; 456 return Service::Audio::ResultInvalidUpdateInfo;
457 } 457 }
458 458
459 input += consumed_input_size; 459 input += consumed_input_size;
@@ -467,18 +467,18 @@ Result InfoUpdater::UpdateBehaviorInfo(BehaviorInfo& behaviour_) {
467 const auto in_params{reinterpret_cast<const BehaviorInfo::InParameter*>(input)}; 467 const auto in_params{reinterpret_cast<const BehaviorInfo::InParameter*>(input)};
468 468
469 if (!CheckValidRevision(in_params->revision)) { 469 if (!CheckValidRevision(in_params->revision)) {
470 return Service::Audio::ERR_INVALID_UPDATE_DATA; 470 return Service::Audio::ResultInvalidUpdateInfo;
471 } 471 }
472 472
473 if (in_params->revision != behaviour_.GetUserRevision()) { 473 if (in_params->revision != behaviour_.GetUserRevision()) {
474 return Service::Audio::ERR_INVALID_UPDATE_DATA; 474 return Service::Audio::ResultInvalidUpdateInfo;
475 } 475 }
476 476
477 behaviour_.ClearError(); 477 behaviour_.ClearError();
478 behaviour_.UpdateFlags(in_params->flags); 478 behaviour_.UpdateFlags(in_params->flags);
479 479
480 if (in_header->behaviour_size != sizeof(BehaviorInfo::InParameter)) { 480 if (in_header->behaviour_size != sizeof(BehaviorInfo::InParameter)) {
481 return Service::Audio::ERR_INVALID_UPDATE_DATA; 481 return Service::Audio::ResultInvalidUpdateInfo;
482 } 482 }
483 483
484 input += sizeof(BehaviorInfo::InParameter); 484 input += sizeof(BehaviorInfo::InParameter);
@@ -500,7 +500,7 @@ Result InfoUpdater::UpdateErrorInfo(const BehaviorInfo& behaviour_) {
500Result InfoUpdater::UpdateSplitterInfo(SplitterContext& splitter_context) { 500Result InfoUpdater::UpdateSplitterInfo(SplitterContext& splitter_context) {
501 u32 consumed_size{0}; 501 u32 consumed_size{0};
502 if (!splitter_context.Update(input, consumed_size)) { 502 if (!splitter_context.Update(input, consumed_size)) {
503 return Service::Audio::ERR_INVALID_UPDATE_DATA; 503 return Service::Audio::ResultInvalidUpdateInfo;
504 } 504 }
505 505
506 input += consumed_size; 506 input += consumed_size;
@@ -529,9 +529,9 @@ Result InfoUpdater::UpdateRendererInfo(const u64 elapsed_frames) {
529 529
530Result InfoUpdater::CheckConsumedSize() { 530Result InfoUpdater::CheckConsumedSize() {
531 if (CpuAddr(input) - CpuAddr(input_origin.data()) != expected_input_size) { 531 if (CpuAddr(input) - CpuAddr(input_origin.data()) != expected_input_size) {
532 return Service::Audio::ERR_INVALID_UPDATE_DATA; 532 return Service::Audio::ResultInvalidUpdateInfo;
533 } else if (CpuAddr(output) - CpuAddr(output_origin.data()) != expected_output_size) { 533 } else if (CpuAddr(output) - CpuAddr(output_origin.data()) != expected_output_size) {
534 return Service::Audio::ERR_INVALID_UPDATE_DATA; 534 return Service::Audio::ResultInvalidUpdateInfo;
535 } 535 }
536 return ResultSuccess; 536 return ResultSuccess;
537} 537}
diff --git a/src/audio_core/renderer/command/effect/reverb.cpp b/src/audio_core/renderer/command/effect/reverb.cpp
index 6fe844ff0..8b9b65214 100644
--- a/src/audio_core/renderer/command/effect/reverb.cpp
+++ b/src/audio_core/renderer/command/effect/reverb.cpp
@@ -308,7 +308,8 @@ static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, Rever
308 } 308 }
309 309
310 Common::FixedPoint<50, 14> pre_delay_sample{ 310 Common::FixedPoint<50, 14> pre_delay_sample{
311 state.pre_delay_line.Read() * Common::FixedPoint<50, 14>::from_base(params.late_gain)}; 311 state.pre_delay_line.TapOut(state.pre_delay_time) *
312 Common::FixedPoint<50, 14>::from_base(params.late_gain)};
312 313
313 std::array<Common::FixedPoint<50, 14>, ReverbInfo::MaxDelayLines> mix_matrix{ 314 std::array<Common::FixedPoint<50, 14>, ReverbInfo::MaxDelayLines> mix_matrix{
314 state.prev_feedback_output[2] + state.prev_feedback_output[1] + pre_delay_sample, 315 state.prev_feedback_output[2] + state.prev_feedback_output[1] + pre_delay_sample,
diff --git a/src/audio_core/renderer/effect/i3dl2.h b/src/audio_core/renderer/effect/i3dl2.h
index 1ebbc5c4c..6e3ffd1d4 100644
--- a/src/audio_core/renderer/effect/i3dl2.h
+++ b/src/audio_core/renderer/effect/i3dl2.h
@@ -104,7 +104,8 @@ public:
104 } 104 }
105 105
106 void Write(const Common::FixedPoint<50, 14> sample) { 106 void Write(const Common::FixedPoint<50, 14> sample) {
107 *(input++) = sample; 107 *input = sample;
108 input++;
108 if (input >= buffer_end) { 109 if (input >= buffer_end) {
109 input = buffer.data(); 110 input = buffer.data();
110 } 111 }
diff --git a/src/audio_core/renderer/effect/reverb.h b/src/audio_core/renderer/effect/reverb.h
index a72475c3c..6cc345ef6 100644
--- a/src/audio_core/renderer/effect/reverb.h
+++ b/src/audio_core/renderer/effect/reverb.h
@@ -79,12 +79,10 @@ public:
79 return; 79 return;
80 } 80 }
81 sample_count = delay_time; 81 sample_count = delay_time;
82 input = &buffer[(output - buffer.data() + sample_count) % (sample_count_max + 1)]; 82 input = &buffer[0];
83 } 83 }
84 84
85 Common::FixedPoint<50, 14> Tick(const Common::FixedPoint<50, 14> sample) { 85 Common::FixedPoint<50, 14> Tick(const Common::FixedPoint<50, 14> sample) {
86 Write(sample);
87
88 auto out_sample{Read()}; 86 auto out_sample{Read()};
89 87
90 output++; 88 output++;
@@ -92,6 +90,7 @@ public:
92 output = buffer.data(); 90 output = buffer.data();
93 } 91 }
94 92
93 Write(sample);
95 return out_sample; 94 return out_sample;
96 } 95 }
97 96
@@ -100,7 +99,8 @@ public:
100 } 99 }
101 100
102 void Write(const Common::FixedPoint<50, 14> sample) { 101 void Write(const Common::FixedPoint<50, 14> sample) {
103 *(input++) = sample; 102 *input = sample;
103 input++;
104 if (input >= buffer_end) { 104 if (input >= buffer_end) {
105 input = buffer.data(); 105 input = buffer.data();
106 } 106 }
diff --git a/src/audio_core/renderer/memory/pool_mapper.cpp b/src/audio_core/renderer/memory/pool_mapper.cpp
index 2baf2ce08..7fd2b5f47 100644
--- a/src/audio_core/renderer/memory/pool_mapper.cpp
+++ b/src/audio_core/renderer/memory/pool_mapper.cpp
@@ -92,7 +92,7 @@ bool PoolMapper::TryAttachBuffer(BehaviorInfo::ErrorInfo& error_info, AddressInf
92 address_info.Setup(address, size); 92 address_info.Setup(address, size);
93 93
94 if (!FillDspAddr(address_info)) { 94 if (!FillDspAddr(address_info)) {
95 error_info.error_code = Service::Audio::ERR_POOL_MAPPING_FAILED; 95 error_info.error_code = Service::Audio::ResultInvalidAddressInfo;
96 error_info.address = address; 96 error_info.address = address;
97 return force_map; 97 return force_map;
98 } 98 }
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp
index 31cbee282..28f063641 100644
--- a/src/audio_core/renderer/system.cpp
+++ b/src/audio_core/renderer/system.cpp
@@ -101,15 +101,15 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
101 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, 101 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
102 u32 process_handle_, u64 applet_resource_user_id_, s32 session_id_) { 102 u32 process_handle_, u64 applet_resource_user_id_, s32 session_id_) {
103 if (!CheckValidRevision(params.revision)) { 103 if (!CheckValidRevision(params.revision)) {
104 return Service::Audio::ERR_INVALID_REVISION; 104 return Service::Audio::ResultInvalidRevision;
105 } 105 }
106 106
107 if (GetWorkBufferSize(params) > transfer_memory_size) { 107 if (GetWorkBufferSize(params) > transfer_memory_size) {
108 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 108 return Service::Audio::ResultInsufficientBuffer;
109 } 109 }
110 110
111 if (process_handle_ == 0) { 111 if (process_handle_ == 0) {
112 return Service::Audio::ERR_INVALID_PROCESS_HANDLE; 112 return Service::Audio::ResultInvalidHandle;
113 } 113 }
114 114
115 behavior.SetUserLibRevision(params.revision); 115 behavior.SetUserLibRevision(params.revision);
@@ -143,19 +143,19 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
143 samples_workbuffer = 143 samples_workbuffer =
144 allocator.Allocate<s32>((voice_channels + mix_buffer_count) * sample_count, 0x10); 144 allocator.Allocate<s32>((voice_channels + mix_buffer_count) * sample_count, 0x10);
145 if (samples_workbuffer.empty()) { 145 if (samples_workbuffer.empty()) {
146 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 146 return Service::Audio::ResultInsufficientBuffer;
147 } 147 }
148 148
149 auto upsampler_workbuffer{allocator.Allocate<s32>( 149 auto upsampler_workbuffer{allocator.Allocate<s32>(
150 (voice_channels + mix_buffer_count) * TargetSampleCount * upsampler_count, 0x10)}; 150 (voice_channels + mix_buffer_count) * TargetSampleCount * upsampler_count, 0x10)};
151 if (upsampler_workbuffer.empty()) { 151 if (upsampler_workbuffer.empty()) {
152 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 152 return Service::Audio::ResultInsufficientBuffer;
153 } 153 }
154 154
155 depop_buffer = 155 depop_buffer =
156 allocator.Allocate<s32>(Common::AlignUp(static_cast<u32>(mix_buffer_count), 0x40), 0x40); 156 allocator.Allocate<s32>(Common::AlignUp(static_cast<u32>(mix_buffer_count), 0x40), 0x40);
157 if (depop_buffer.empty()) { 157 if (depop_buffer.empty()) {
158 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 158 return Service::Audio::ResultInsufficientBuffer;
159 } 159 }
160 160
161 // invalidate samples_workbuffer DSP cache 161 // invalidate samples_workbuffer DSP cache
@@ -166,12 +166,12 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
166 } 166 }
167 167
168 if (voice_infos.empty()) { 168 if (voice_infos.empty()) {
169 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 169 return Service::Audio::ResultInsufficientBuffer;
170 } 170 }
171 171
172 auto sorted_voice_infos{allocator.Allocate<VoiceInfo*>(params.voices, 0x10)}; 172 auto sorted_voice_infos{allocator.Allocate<VoiceInfo*>(params.voices, 0x10)};
173 if (sorted_voice_infos.empty()) { 173 if (sorted_voice_infos.empty()) {
174 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 174 return Service::Audio::ResultInsufficientBuffer;
175 } 175 }
176 176
177 std::memset(sorted_voice_infos.data(), 0, sorted_voice_infos.size_bytes()); 177 std::memset(sorted_voice_infos.data(), 0, sorted_voice_infos.size_bytes());
@@ -183,12 +183,12 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
183 } 183 }
184 184
185 if (voice_channel_resources.empty()) { 185 if (voice_channel_resources.empty()) {
186 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 186 return Service::Audio::ResultInsufficientBuffer;
187 } 187 }
188 188
189 auto voice_cpu_states{allocator.Allocate<VoiceState>(params.voices, 0x10)}; 189 auto voice_cpu_states{allocator.Allocate<VoiceState>(params.voices, 0x10)};
190 if (voice_cpu_states.empty()) { 190 if (voice_cpu_states.empty()) {
191 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 191 return Service::Audio::ResultInsufficientBuffer;
192 } 192 }
193 193
194 for (auto& voice_state : voice_cpu_states) { 194 for (auto& voice_state : voice_cpu_states) {
@@ -198,7 +198,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
198 auto mix_infos{allocator.Allocate<MixInfo>(params.sub_mixes + 1, 0x10)}; 198 auto mix_infos{allocator.Allocate<MixInfo>(params.sub_mixes + 1, 0x10)};
199 199
200 if (mix_infos.empty()) { 200 if (mix_infos.empty()) {
201 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 201 return Service::Audio::ResultInsufficientBuffer;
202 } 202 }
203 203
204 u32 effect_process_order_count{0}; 204 u32 effect_process_order_count{0};
@@ -208,7 +208,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
208 effect_process_order_count = params.effects * (params.sub_mixes + 1); 208 effect_process_order_count = params.effects * (params.sub_mixes + 1);
209 effect_process_order_buffer = allocator.Allocate<s32>(effect_process_order_count, 0x10); 209 effect_process_order_buffer = allocator.Allocate<s32>(effect_process_order_count, 0x10);
210 if (effect_process_order_buffer.empty()) { 210 if (effect_process_order_buffer.empty()) {
211 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 211 return Service::Audio::ResultInsufficientBuffer;
212 } 212 }
213 } 213 }
214 214
@@ -222,7 +222,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
222 222
223 auto sorted_mix_infos{allocator.Allocate<MixInfo*>(params.sub_mixes + 1, 0x10)}; 223 auto sorted_mix_infos{allocator.Allocate<MixInfo*>(params.sub_mixes + 1, 0x10)};
224 if (sorted_mix_infos.empty()) { 224 if (sorted_mix_infos.empty()) {
225 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 225 return Service::Audio::ResultInsufficientBuffer;
226 } 226 }
227 227
228 std::memset(sorted_mix_infos.data(), 0, sorted_mix_infos.size_bytes()); 228 std::memset(sorted_mix_infos.data(), 0, sorted_mix_infos.size_bytes());
@@ -235,7 +235,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
235 auto edge_matrix_workbuffer{allocator.Allocate<u8>(edge_matrix_size, 1)}; 235 auto edge_matrix_workbuffer{allocator.Allocate<u8>(edge_matrix_size, 1)};
236 236
237 if (node_states_workbuffer.empty() || edge_matrix_workbuffer.size() == 0) { 237 if (node_states_workbuffer.empty() || edge_matrix_workbuffer.size() == 0) {
238 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 238 return Service::Audio::ResultInsufficientBuffer;
239 } 239 }
240 240
241 mix_context.Initialize(sorted_mix_infos, mix_infos, params.sub_mixes + 1, 241 mix_context.Initialize(sorted_mix_infos, mix_infos, params.sub_mixes + 1,
@@ -250,7 +250,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
250 250
251 upsampler_manager = allocator.Allocate<UpsamplerManager>(1, 0x10).data(); 251 upsampler_manager = allocator.Allocate<UpsamplerManager>(1, 0x10).data();
252 if (upsampler_manager == nullptr) { 252 if (upsampler_manager == nullptr) {
253 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 253 return Service::Audio::ResultInsufficientBuffer;
254 } 254 }
255 255
256 memory_pool_workbuffer = allocator.Allocate<MemoryPoolInfo>(memory_pool_count, 0x10); 256 memory_pool_workbuffer = allocator.Allocate<MemoryPoolInfo>(memory_pool_count, 0x10);
@@ -259,18 +259,18 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
259 } 259 }
260 260
261 if (memory_pool_workbuffer.empty() && memory_pool_count > 0) { 261 if (memory_pool_workbuffer.empty() && memory_pool_count > 0) {
262 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 262 return Service::Audio::ResultInsufficientBuffer;
263 } 263 }
264 264
265 if (!splitter_context.Initialize(behavior, params, allocator)) { 265 if (!splitter_context.Initialize(behavior, params, allocator)) {
266 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 266 return Service::Audio::ResultInsufficientBuffer;
267 } 267 }
268 268
269 std::span<EffectResultState> effect_result_states_cpu{}; 269 std::span<EffectResultState> effect_result_states_cpu{};
270 if (behavior.IsEffectInfoVersion2Supported() && params.effects > 0) { 270 if (behavior.IsEffectInfoVersion2Supported() && params.effects > 0) {
271 effect_result_states_cpu = allocator.Allocate<EffectResultState>(params.effects, 0x10); 271 effect_result_states_cpu = allocator.Allocate<EffectResultState>(params.effects, 0x10);
272 if (effect_result_states_cpu.empty()) { 272 if (effect_result_states_cpu.empty()) {
273 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 273 return Service::Audio::ResultInsufficientBuffer;
274 } 274 }
275 std::memset(effect_result_states_cpu.data(), 0, effect_result_states_cpu.size_bytes()); 275 std::memset(effect_result_states_cpu.data(), 0, effect_result_states_cpu.size_bytes());
276 } 276 }
@@ -289,7 +289,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
289 upsampler_workbuffer); 289 upsampler_workbuffer);
290 290
291 if (upsampler_infos.empty()) { 291 if (upsampler_infos.empty()) {
292 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 292 return Service::Audio::ResultInsufficientBuffer;
293 } 293 }
294 294
295 auto effect_infos{allocator.Allocate<EffectInfoBase>(params.effects, 0x40)}; 295 auto effect_infos{allocator.Allocate<EffectInfoBase>(params.effects, 0x40)};
@@ -298,14 +298,14 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
298 } 298 }
299 299
300 if (effect_infos.empty() && params.effects > 0) { 300 if (effect_infos.empty() && params.effects > 0) {
301 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 301 return Service::Audio::ResultInsufficientBuffer;
302 } 302 }
303 303
304 std::span<EffectResultState> effect_result_states_dsp{}; 304 std::span<EffectResultState> effect_result_states_dsp{};
305 if (behavior.IsEffectInfoVersion2Supported() && params.effects > 0) { 305 if (behavior.IsEffectInfoVersion2Supported() && params.effects > 0) {
306 effect_result_states_dsp = allocator.Allocate<EffectResultState>(params.effects, 0x40); 306 effect_result_states_dsp = allocator.Allocate<EffectResultState>(params.effects, 0x40);
307 if (effect_result_states_dsp.empty()) { 307 if (effect_result_states_dsp.empty()) {
308 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 308 return Service::Audio::ResultInsufficientBuffer;
309 } 309 }
310 std::memset(effect_result_states_dsp.data(), 0, effect_result_states_dsp.size_bytes()); 310 std::memset(effect_result_states_dsp.data(), 0, effect_result_states_dsp.size_bytes());
311 } 311 }
@@ -319,14 +319,14 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
319 } 319 }
320 320
321 if (sinks.empty()) { 321 if (sinks.empty()) {
322 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 322 return Service::Audio::ResultInsufficientBuffer;
323 } 323 }
324 324
325 sink_context.Initialize(sinks, params.sinks); 325 sink_context.Initialize(sinks, params.sinks);
326 326
327 auto voice_dsp_states{allocator.Allocate<VoiceState>(params.voices, 0x40)}; 327 auto voice_dsp_states{allocator.Allocate<VoiceState>(params.voices, 0x40)};
328 if (voice_dsp_states.empty()) { 328 if (voice_dsp_states.empty()) {
329 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 329 return Service::Audio::ResultInsufficientBuffer;
330 } 330 }
331 331
332 for (auto& voice_state : voice_dsp_states) { 332 for (auto& voice_state : voice_dsp_states) {
@@ -344,7 +344,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
344 0xC}; 344 0xC};
345 performance_workbuffer = allocator.Allocate<u8>(perf_workbuffer_size, 0x40); 345 performance_workbuffer = allocator.Allocate<u8>(perf_workbuffer_size, 0x40);
346 if (performance_workbuffer.empty()) { 346 if (performance_workbuffer.empty()) {
347 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 347 return Service::Audio::ResultInsufficientBuffer;
348 } 348 }
349 std::memset(performance_workbuffer.data(), 0, performance_workbuffer.size_bytes()); 349 std::memset(performance_workbuffer.data(), 0, performance_workbuffer.size_bytes());
350 performance_manager.Initialize(performance_workbuffer, performance_workbuffer.size_bytes(), 350 performance_manager.Initialize(performance_workbuffer, performance_workbuffer.size_bytes(),
@@ -360,7 +360,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
360 command_workbuffer_size = allocator.GetRemainingSize(); 360 command_workbuffer_size = allocator.GetRemainingSize();
361 command_workbuffer = allocator.Allocate<u8>(command_workbuffer_size, 0x40); 361 command_workbuffer = allocator.Allocate<u8>(command_workbuffer_size, 0x40);
362 if (command_workbuffer.empty()) { 362 if (command_workbuffer.empty()) {
363 return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE; 363 return Service::Audio::ResultInsufficientBuffer;
364 } 364 }
365 365
366 command_buffer_size = 0; 366 command_buffer_size = 0;
diff --git a/src/audio_core/renderer/voice/voice_info.cpp b/src/audio_core/renderer/voice/voice_info.cpp
index 1849eeb57..c0bfb23fc 100644
--- a/src/audio_core/renderer/voice/voice_info.cpp
+++ b/src/audio_core/renderer/voice/voice_info.cpp
@@ -181,7 +181,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info,
181 if (wave_buffer_internal.start_offset * byte_size > wave_buffer_internal.size || 181 if (wave_buffer_internal.start_offset * byte_size > wave_buffer_internal.size ||
182 wave_buffer_internal.end_offset * byte_size > wave_buffer_internal.size) { 182 wave_buffer_internal.end_offset * byte_size > wave_buffer_internal.size) {
183 LOG_ERROR(Service_Audio, "Invalid PCM16 start/end wavebuffer sizes!"); 183 LOG_ERROR(Service_Audio, "Invalid PCM16 start/end wavebuffer sizes!");
184 error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA; 184 error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo;
185 error_info[0].address = wave_buffer_internal.address; 185 error_info[0].address = wave_buffer_internal.address;
186 return; 186 return;
187 } 187 }
@@ -192,7 +192,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info,
192 if (wave_buffer_internal.start_offset * byte_size > wave_buffer_internal.size || 192 if (wave_buffer_internal.start_offset * byte_size > wave_buffer_internal.size ||
193 wave_buffer_internal.end_offset * byte_size > wave_buffer_internal.size) { 193 wave_buffer_internal.end_offset * byte_size > wave_buffer_internal.size) {
194 LOG_ERROR(Service_Audio, "Invalid PCMFloat start/end wavebuffer sizes!"); 194 LOG_ERROR(Service_Audio, "Invalid PCMFloat start/end wavebuffer sizes!");
195 error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA; 195 error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo;
196 error_info[0].address = wave_buffer_internal.address; 196 error_info[0].address = wave_buffer_internal.address;
197 return; 197 return;
198 } 198 }
@@ -216,7 +216,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info,
216 if (start > static_cast<s64>(wave_buffer_internal.size) || 216 if (start > static_cast<s64>(wave_buffer_internal.size) ||
217 end > static_cast<s64>(wave_buffer_internal.size)) { 217 end > static_cast<s64>(wave_buffer_internal.size)) {
218 LOG_ERROR(Service_Audio, "Invalid ADPCM start/end wavebuffer sizes!"); 218 LOG_ERROR(Service_Audio, "Invalid ADPCM start/end wavebuffer sizes!");
219 error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA; 219 error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo;
220 error_info[0].address = wave_buffer_internal.address; 220 error_info[0].address = wave_buffer_internal.address;
221 return; 221 return;
222 } 222 }
@@ -228,7 +228,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info,
228 228
229 if (wave_buffer_internal.start_offset < 0 || wave_buffer_internal.end_offset < 0) { 229 if (wave_buffer_internal.start_offset < 0 || wave_buffer_internal.end_offset < 0) {
230 LOG_ERROR(Service_Audio, "Invalid input start/end wavebuffer sizes!"); 230 LOG_ERROR(Service_Audio, "Invalid input start/end wavebuffer sizes!");
231 error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA; 231 error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo;
232 error_info[0].address = wave_buffer_internal.address; 232 error_info[0].address = wave_buffer_internal.address;
233 return; 233 return;
234 } 234 }
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 9884a4a0b..61ab68864 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -91,6 +91,7 @@ add_library(common STATIC
91 multi_level_page_table.h 91 multi_level_page_table.h
92 nvidia_flags.cpp 92 nvidia_flags.cpp
93 nvidia_flags.h 93 nvidia_flags.h
94 overflow.h
94 page_table.cpp 95 page_table.cpp
95 page_table.h 96 page_table.h
96 param_package.cpp 97 param_package.cpp
@@ -113,6 +114,8 @@ add_library(common STATIC
113 socket_types.h 114 socket_types.h
114 spin_lock.cpp 115 spin_lock.cpp
115 spin_lock.h 116 spin_lock.h
117 steady_clock.cpp
118 steady_clock.h
116 stream.cpp 119 stream.cpp
117 stream.h 120 stream.h
118 string_util.cpp 121 string_util.cpp
@@ -142,6 +145,14 @@ add_library(common STATIC
142 zstd_compression.h 145 zstd_compression.h
143) 146)
144 147
148if (WIN32)
149 target_sources(common PRIVATE
150 windows/timer_resolution.cpp
151 windows/timer_resolution.h
152 )
153 target_link_libraries(common PRIVATE ntdll)
154endif()
155
145if(ARCHITECTURE_x86_64) 156if(ARCHITECTURE_x86_64)
146 target_sources(common 157 target_sources(common
147 PRIVATE 158 PRIVATE
@@ -176,7 +187,7 @@ endif()
176 187
177create_target_directory_groups(common) 188create_target_directory_groups(common)
178 189
179target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile Threads::Threads) 190target_link_libraries(common PUBLIC Boost::context Boost::headers fmt::fmt microprofile Threads::Threads)
180target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle) 191target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle)
181 192
182if (YUZU_USE_PRECOMPILED_HEADERS) 193if (YUZU_USE_PRECOMPILED_HEADERS)
diff --git a/src/common/bit_cast.h b/src/common/bit_cast.h
index 535148b4d..c6110c542 100644
--- a/src/common/bit_cast.h
+++ b/src/common/bit_cast.h
@@ -3,19 +3,21 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <cstring> 6#include <version>
7#include <type_traits> 7
8#ifdef __cpp_lib_bit_cast
9#include <bit>
10#endif
8 11
9namespace Common { 12namespace Common {
10 13
11template <typename To, typename From> 14template <typename To, typename From>
12[[nodiscard]] std::enable_if_t<sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From> && 15constexpr inline To BitCast(const From& from) {
13 std::is_trivially_copyable_v<To>, 16#ifdef __cpp_lib_bit_cast
14 To> 17 return std::bit_cast<To>(from);
15BitCast(const From& src) noexcept { 18#else
16 To dst; 19 return __builtin_bit_cast(To, from);
17 std::memcpy(&dst, &src, sizeof(To)); 20#endif
18 return dst;
19} 21}
20 22
21} // namespace Common 23} // namespace Common
diff --git a/src/common/input.h b/src/common/input.h
index b5748a6c8..98e934685 100644
--- a/src/common/input.h
+++ b/src/common/input.h
@@ -46,7 +46,7 @@ enum class PollingMode {
46 // Constant polling of buttons, analogs and motion data 46 // Constant polling of buttons, analogs and motion data
47 Active, 47 Active,
48 // Only update on button change, digital analogs 48 // Only update on button change, digital analogs
49 Pasive, 49 Passive,
50 // Enable near field communication polling 50 // Enable near field communication polling
51 NFC, 51 NFC,
52 // Enable infrared camera polling 52 // Enable infrared camera polling
diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp
index a959acb74..c95909561 100644
--- a/src/common/logging/filter.cpp
+++ b/src/common/logging/filter.cpp
@@ -119,7 +119,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
119 SUB(Service, NPNS) \ 119 SUB(Service, NPNS) \
120 SUB(Service, NS) \ 120 SUB(Service, NS) \
121 SUB(Service, NVDRV) \ 121 SUB(Service, NVDRV) \
122 SUB(Service, NVFlinger) \ 122 SUB(Service, Nvnflinger) \
123 SUB(Service, OLSC) \ 123 SUB(Service, OLSC) \
124 SUB(Service, PCIE) \ 124 SUB(Service, PCIE) \
125 SUB(Service, PCTL) \ 125 SUB(Service, PCTL) \
diff --git a/src/common/logging/types.h b/src/common/logging/types.h
index 595c15ada..8356e3183 100644
--- a/src/common/logging/types.h
+++ b/src/common/logging/types.h
@@ -29,107 +29,107 @@ enum class Level : u8 {
29 * filter.cpp. 29 * filter.cpp.
30 */ 30 */
31enum class Class : u8 { 31enum class Class : u8 {
32 Log, ///< Messages about the log system itself 32 Log, ///< Messages about the log system itself
33 Common, ///< Library routines 33 Common, ///< Library routines
34 Common_Filesystem, ///< Filesystem interface library 34 Common_Filesystem, ///< Filesystem interface library
35 Common_Memory, ///< Memory mapping and management functions 35 Common_Memory, ///< Memory mapping and management functions
36 Core, ///< LLE emulation core 36 Core, ///< LLE emulation core
37 Core_ARM, ///< ARM CPU core 37 Core_ARM, ///< ARM CPU core
38 Core_Timing, ///< CoreTiming functions 38 Core_Timing, ///< CoreTiming functions
39 Config, ///< Emulator configuration (including commandline) 39 Config, ///< Emulator configuration (including commandline)
40 Debug, ///< Debugging tools 40 Debug, ///< Debugging tools
41 Debug_Emulated, ///< Debug messages from the emulated programs 41 Debug_Emulated, ///< Debug messages from the emulated programs
42 Debug_GPU, ///< GPU debugging tools 42 Debug_GPU, ///< GPU debugging tools
43 Debug_Breakpoint, ///< Logging breakpoints and watchpoints 43 Debug_Breakpoint, ///< Logging breakpoints and watchpoints
44 Debug_GDBStub, ///< GDB Stub 44 Debug_GDBStub, ///< GDB Stub
45 Kernel, ///< The HLE implementation of the CTR kernel 45 Kernel, ///< The HLE implementation of the CTR kernel
46 Kernel_SVC, ///< Kernel system calls 46 Kernel_SVC, ///< Kernel system calls
47 Service, ///< HLE implementation of system services. Each major service 47 Service, ///< HLE implementation of system services. Each major service
48 ///< should have its own subclass. 48 ///< should have its own subclass.
49 Service_ACC, ///< The ACC (Accounts) service 49 Service_ACC, ///< The ACC (Accounts) service
50 Service_AM, ///< The AM (Applet manager) service 50 Service_AM, ///< The AM (Applet manager) service
51 Service_AOC, ///< The AOC (AddOn Content) service 51 Service_AOC, ///< The AOC (AddOn Content) service
52 Service_APM, ///< The APM (Performance) service 52 Service_APM, ///< The APM (Performance) service
53 Service_ARP, ///< The ARP service 53 Service_ARP, ///< The ARP service
54 Service_Audio, ///< The Audio (Audio control) service 54 Service_Audio, ///< The Audio (Audio control) service
55 Service_BCAT, ///< The BCAT service 55 Service_BCAT, ///< The BCAT service
56 Service_BGTC, ///< The BGTC (Background Task Controller) service 56 Service_BGTC, ///< The BGTC (Background Task Controller) service
57 Service_BPC, ///< The BPC service 57 Service_BPC, ///< The BPC service
58 Service_BTDRV, ///< The Bluetooth driver service 58 Service_BTDRV, ///< The Bluetooth driver service
59 Service_BTM, ///< The BTM service 59 Service_BTM, ///< The BTM service
60 Service_Capture, ///< The capture service 60 Service_Capture, ///< The capture service
61 Service_ERPT, ///< The error reporting service 61 Service_ERPT, ///< The error reporting service
62 Service_ETicket, ///< The ETicket service 62 Service_ETicket, ///< The ETicket service
63 Service_EUPLD, ///< The error upload service 63 Service_EUPLD, ///< The error upload service
64 Service_Fatal, ///< The Fatal service 64 Service_Fatal, ///< The Fatal service
65 Service_FGM, ///< The FGM service 65 Service_FGM, ///< The FGM service
66 Service_Friend, ///< The friend service 66 Service_Friend, ///< The friend service
67 Service_FS, ///< The FS (Filesystem) service 67 Service_FS, ///< The FS (Filesystem) service
68 Service_GRC, ///< The game recording service 68 Service_GRC, ///< The game recording service
69 Service_HID, ///< The HID (Human interface device) service 69 Service_HID, ///< The HID (Human interface device) service
70 Service_IRS, ///< The IRS service 70 Service_IRS, ///< The IRS service
71 Service_JIT, ///< The JIT service 71 Service_JIT, ///< The JIT service
72 Service_LBL, ///< The LBL (LCD backlight) service 72 Service_LBL, ///< The LBL (LCD backlight) service
73 Service_LDN, ///< The LDN (Local domain network) service 73 Service_LDN, ///< The LDN (Local domain network) service
74 Service_LDR, ///< The loader service 74 Service_LDR, ///< The loader service
75 Service_LM, ///< The LM (Logger) service 75 Service_LM, ///< The LM (Logger) service
76 Service_Migration, ///< The migration service 76 Service_Migration, ///< The migration service
77 Service_Mii, ///< The Mii service 77 Service_Mii, ///< The Mii service
78 Service_MM, ///< The MM (Multimedia) service 78 Service_MM, ///< The MM (Multimedia) service
79 Service_MNPP, ///< The MNPP service 79 Service_MNPP, ///< The MNPP service
80 Service_NCM, ///< The NCM service 80 Service_NCM, ///< The NCM service
81 Service_NFC, ///< The NFC (Near-field communication) service 81 Service_NFC, ///< The NFC (Near-field communication) service
82 Service_NFP, ///< The NFP service 82 Service_NFP, ///< The NFP service
83 Service_NGCT, ///< The NGCT (No Good Content for Terra) service 83 Service_NGCT, ///< The NGCT (No Good Content for Terra) service
84 Service_NIFM, ///< The NIFM (Network interface) service 84 Service_NIFM, ///< The NIFM (Network interface) service
85 Service_NIM, ///< The NIM service 85 Service_NIM, ///< The NIM service
86 Service_NOTIF, ///< The NOTIF (Notification) service 86 Service_NOTIF, ///< The NOTIF (Notification) service
87 Service_NPNS, ///< The NPNS service 87 Service_NPNS, ///< The NPNS service
88 Service_NS, ///< The NS services 88 Service_NS, ///< The NS services
89 Service_NVDRV, ///< The NVDRV (Nvidia driver) service 89 Service_NVDRV, ///< The NVDRV (Nvidia driver) service
90 Service_NVFlinger, ///< The NVFlinger service 90 Service_Nvnflinger, ///< The Nvnflinger service
91 Service_OLSC, ///< The OLSC service 91 Service_OLSC, ///< The OLSC service
92 Service_PCIE, ///< The PCIe service 92 Service_PCIE, ///< The PCIe service
93 Service_PCTL, ///< The PCTL (Parental control) service 93 Service_PCTL, ///< The PCTL (Parental control) service
94 Service_PCV, ///< The PCV service 94 Service_PCV, ///< The PCV service
95 Service_PM, ///< The PM service 95 Service_PM, ///< The PM service
96 Service_PREPO, ///< The PREPO (Play report) service 96 Service_PREPO, ///< The PREPO (Play report) service
97 Service_PSC, ///< The PSC service 97 Service_PSC, ///< The PSC service
98 Service_PTM, ///< The PTM service 98 Service_PTM, ///< The PTM service
99 Service_SET, ///< The SET (Settings) service 99 Service_SET, ///< The SET (Settings) service
100 Service_SM, ///< The SM (Service manager) service 100 Service_SM, ///< The SM (Service manager) service
101 Service_SPL, ///< The SPL service 101 Service_SPL, ///< The SPL service
102 Service_SSL, ///< The SSL service 102 Service_SSL, ///< The SSL service
103 Service_TCAP, ///< The TCAP service. 103 Service_TCAP, ///< The TCAP service.
104 Service_Time, ///< The time service 104 Service_Time, ///< The time service
105 Service_USB, ///< The USB (Universal Serial Bus) service 105 Service_USB, ///< The USB (Universal Serial Bus) service
106 Service_VI, ///< The VI (Video interface) service 106 Service_VI, ///< The VI (Video interface) service
107 Service_WLAN, ///< The WLAN (Wireless local area network) service 107 Service_WLAN, ///< The WLAN (Wireless local area network) service
108 HW, ///< Low-level hardware emulation 108 HW, ///< Low-level hardware emulation
109 HW_Memory, ///< Memory-map and address translation 109 HW_Memory, ///< Memory-map and address translation
110 HW_LCD, ///< LCD register emulation 110 HW_LCD, ///< LCD register emulation
111 HW_GPU, ///< GPU control emulation 111 HW_GPU, ///< GPU control emulation
112 HW_AES, ///< AES engine emulation 112 HW_AES, ///< AES engine emulation
113 IPC, ///< IPC interface 113 IPC, ///< IPC interface
114 Frontend, ///< Emulator UI 114 Frontend, ///< Emulator UI
115 Render, ///< Emulator video output and hardware acceleration 115 Render, ///< Emulator video output and hardware acceleration
116 Render_Software, ///< Software renderer backend 116 Render_Software, ///< Software renderer backend
117 Render_OpenGL, ///< OpenGL backend 117 Render_OpenGL, ///< OpenGL backend
118 Render_Vulkan, ///< Vulkan backend 118 Render_Vulkan, ///< Vulkan backend
119 Shader, ///< Shader recompiler 119 Shader, ///< Shader recompiler
120 Shader_SPIRV, ///< Shader SPIR-V code generation 120 Shader_SPIRV, ///< Shader SPIR-V code generation
121 Shader_GLASM, ///< Shader GLASM code generation 121 Shader_GLASM, ///< Shader GLASM code generation
122 Shader_GLSL, ///< Shader GLSL code generation 122 Shader_GLSL, ///< Shader GLSL code generation
123 Audio, ///< Audio emulation 123 Audio, ///< Audio emulation
124 Audio_DSP, ///< The HLE implementation of the DSP 124 Audio_DSP, ///< The HLE implementation of the DSP
125 Audio_Sink, ///< Emulator audio output backend 125 Audio_Sink, ///< Emulator audio output backend
126 Loader, ///< ROM loader 126 Loader, ///< ROM loader
127 CheatEngine, ///< Memory manipulation and engine VM functions 127 CheatEngine, ///< Memory manipulation and engine VM functions
128 Crypto, ///< Cryptographic engine/functions 128 Crypto, ///< Cryptographic engine/functions
129 Input, ///< Input emulation 129 Input, ///< Input emulation
130 Network, ///< Network emulation 130 Network, ///< Network emulation
131 WebService, ///< Interface to yuzu Web Services 131 WebService, ///< Interface to yuzu Web Services
132 Count ///< Total number of logging classes 132 Count ///< Total number of logging classes
133}; 133};
134 134
135} // namespace Common::Log 135} // namespace Common::Log
diff --git a/src/common/overflow.h b/src/common/overflow.h
new file mode 100644
index 000000000..44d8e7e73
--- /dev/null
+++ b/src/common/overflow.h
@@ -0,0 +1,22 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <type_traits>
7#include "bit_cast.h"
8
9namespace Common {
10
11template <typename T>
12 requires(std::is_integral_v<T> && std::is_signed_v<T>)
13inline T WrappingAdd(T lhs, T rhs) {
14 using U = std::make_unsigned_t<T>;
15
16 U lhs_u = BitCast<U>(lhs);
17 U rhs_u = BitCast<U>(rhs);
18
19 return BitCast<T>(lhs_u + rhs_u);
20}
21
22} // namespace Common
diff --git a/src/common/scratch_buffer.h b/src/common/scratch_buffer.h
index 1245a5086..26d4e76dc 100644
--- a/src/common/scratch_buffer.h
+++ b/src/common/scratch_buffer.h
@@ -23,6 +23,7 @@ public:
23 buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {} 23 buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {}
24 24
25 ~ScratchBuffer() = default; 25 ~ScratchBuffer() = default;
26 ScratchBuffer(ScratchBuffer&&) = default;
26 27
27 /// This will only grow the buffer's capacity if size is greater than the current capacity. 28 /// This will only grow the buffer's capacity if size is greater than the current capacity.
28 /// The previously held data will remain intact. 29 /// The previously held data will remain intact.
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 749ac213f..84955030b 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -59,6 +59,7 @@ void LogSettings() {
59 values.use_asynchronous_gpu_emulation.GetValue()); 59 values.use_asynchronous_gpu_emulation.GetValue());
60 log_setting("Renderer_NvdecEmulation", values.nvdec_emulation.GetValue()); 60 log_setting("Renderer_NvdecEmulation", values.nvdec_emulation.GetValue());
61 log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue()); 61 log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue());
62 log_setting("Renderer_AsyncASTC", values.async_astc.GetValue());
62 log_setting("Renderer_UseVsync", values.use_vsync.GetValue()); 63 log_setting("Renderer_UseVsync", values.use_vsync.GetValue());
63 log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue()); 64 log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue());
64 log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); 65 log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
@@ -219,6 +220,7 @@ void RestoreGlobalState(bool is_powered_on) {
219 values.use_asynchronous_gpu_emulation.SetGlobal(true); 220 values.use_asynchronous_gpu_emulation.SetGlobal(true);
220 values.nvdec_emulation.SetGlobal(true); 221 values.nvdec_emulation.SetGlobal(true);
221 values.accelerate_astc.SetGlobal(true); 222 values.accelerate_astc.SetGlobal(true);
223 values.async_astc.SetGlobal(true);
222 values.use_vsync.SetGlobal(true); 224 values.use_vsync.SetGlobal(true);
223 values.shader_backend.SetGlobal(true); 225 values.shader_backend.SetGlobal(true);
224 values.use_asynchronous_shaders.SetGlobal(true); 226 values.use_asynchronous_shaders.SetGlobal(true);
diff --git a/src/common/settings.h b/src/common/settings.h
index 6d27dd5ee..b77a1580a 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -128,7 +128,7 @@ public:
128 /** 128 /**
129 * Sets a default value, label, and setting value. 129 * Sets a default value, label, and setting value.
130 * 130 *
131 * @param default_val Intial value of the setting, and default value of the setting 131 * @param default_val Initial value of the setting, and default value of the setting
132 * @param name Label for the setting 132 * @param name Label for the setting
133 */ 133 */
134 explicit Setting(const Type& default_val, const std::string& name) 134 explicit Setting(const Type& default_val, const std::string& name)
@@ -139,7 +139,7 @@ public:
139 /** 139 /**
140 * Sets a default value, minimum value, maximum value, and label. 140 * Sets a default value, minimum value, maximum value, and label.
141 * 141 *
142 * @param default_val Intial value of the setting, and default value of the setting 142 * @param default_val Initial value of the setting, and default value of the setting
143 * @param min_val Sets the minimum allowed value of the setting 143 * @param min_val Sets the minimum allowed value of the setting
144 * @param max_val Sets the maximum allowed value of the setting 144 * @param max_val Sets the maximum allowed value of the setting
145 * @param name Label for the setting 145 * @param name Label for the setting
@@ -231,7 +231,7 @@ public:
231 /** 231 /**
232 * Sets a default value, label, and setting value. 232 * Sets a default value, label, and setting value.
233 * 233 *
234 * @param default_val Intial value of the setting, and default value of the setting 234 * @param default_val Initial value of the setting, and default value of the setting
235 * @param name Label for the setting 235 * @param name Label for the setting
236 */ 236 */
237 explicit SwitchableSetting(const Type& default_val, const std::string& name) 237 explicit SwitchableSetting(const Type& default_val, const std::string& name)
@@ -242,7 +242,7 @@ public:
242 /** 242 /**
243 * Sets a default value, minimum value, maximum value, and label. 243 * Sets a default value, minimum value, maximum value, and label.
244 * 244 *
245 * @param default_val Intial value of the setting, and default value of the setting 245 * @param default_val Initial value of the setting, and default value of the setting
246 * @param min_val Sets the minimum allowed value of the setting 246 * @param min_val Sets the minimum allowed value of the setting
247 * @param max_val Sets the maximum allowed value of the setting 247 * @param max_val Sets the maximum allowed value of the setting
248 * @param name Label for the setting 248 * @param name Label for the setting
@@ -453,6 +453,7 @@ struct Values {
453 SwitchableSetting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"}; 453 SwitchableSetting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"};
454 SwitchableSetting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"}; 454 SwitchableSetting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"};
455 SwitchableSetting<bool> accelerate_astc{true, "accelerate_astc"}; 455 SwitchableSetting<bool> accelerate_astc{true, "accelerate_astc"};
456 SwitchableSetting<bool> async_astc{false, "async_astc"};
456 SwitchableSetting<bool> use_vsync{true, "use_vsync"}; 457 SwitchableSetting<bool> use_vsync{true, "use_vsync"};
457 SwitchableSetting<ShaderBackend, true> shader_backend{ShaderBackend::GLSL, ShaderBackend::GLSL, 458 SwitchableSetting<ShaderBackend, true> shader_backend{ShaderBackend::GLSL, ShaderBackend::GLSL,
458 ShaderBackend::SPIRV, "shader_backend"}; 459 ShaderBackend::SPIRV, "shader_backend"};
@@ -502,7 +503,7 @@ struct Values {
502 Setting<bool> tas_loop{false, "tas_loop"}; 503 Setting<bool> tas_loop{false, "tas_loop"};
503 504
504 Setting<bool> mouse_panning{false, "mouse_panning"}; 505 Setting<bool> mouse_panning{false, "mouse_panning"};
505 Setting<u8, true> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"}; 506 Setting<u8, true> mouse_panning_sensitivity{50, 1, 100, "mouse_panning_sensitivity"};
506 Setting<bool> mouse_enabled{false, "mouse_enabled"}; 507 Setting<bool> mouse_enabled{false, "mouse_enabled"};
507 508
508 Setting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"}; 509 Setting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"};
diff --git a/src/common/steady_clock.cpp b/src/common/steady_clock.cpp
new file mode 100644
index 000000000..0d5908aa7
--- /dev/null
+++ b/src/common/steady_clock.cpp
@@ -0,0 +1,56 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#if defined(_WIN32)
5#include <windows.h>
6#else
7#include <time.h>
8#endif
9
10#include "common/steady_clock.h"
11
12namespace Common {
13
14#ifdef _WIN32
15static s64 WindowsQueryPerformanceFrequency() {
16 LARGE_INTEGER frequency;
17 QueryPerformanceFrequency(&frequency);
18 return frequency.QuadPart;
19}
20
21static s64 WindowsQueryPerformanceCounter() {
22 LARGE_INTEGER counter;
23 QueryPerformanceCounter(&counter);
24 return counter.QuadPart;
25}
26#endif
27
28SteadyClock::time_point SteadyClock::Now() noexcept {
29#if defined(_WIN32)
30 static const auto freq = WindowsQueryPerformanceFrequency();
31 const auto counter = WindowsQueryPerformanceCounter();
32
33 // 10 MHz is a very common QPC frequency on modern PCs.
34 // Optimizing for this specific frequency can double the performance of
35 // this function by avoiding the expensive frequency conversion path.
36 static constexpr s64 TenMHz = 10'000'000;
37
38 if (freq == TenMHz) [[likely]] {
39 static_assert(period::den % TenMHz == 0);
40 static constexpr s64 Multiplier = period::den / TenMHz;
41 return time_point{duration{counter * Multiplier}};
42 }
43
44 const auto whole = (counter / freq) * period::den;
45 const auto part = (counter % freq) * period::den / freq;
46 return time_point{duration{whole + part}};
47#elif defined(__APPLE__)
48 return time_point{duration{clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)}};
49#else
50 timespec ts;
51 clock_gettime(CLOCK_MONOTONIC, &ts);
52 return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}};
53#endif
54}
55
56}; // namespace Common
diff --git a/src/common/steady_clock.h b/src/common/steady_clock.h
new file mode 100644
index 000000000..9497cf865
--- /dev/null
+++ b/src/common/steady_clock.h
@@ -0,0 +1,23 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <chrono>
7
8#include "common/common_types.h"
9
10namespace Common {
11
12struct SteadyClock {
13 using rep = s64;
14 using period = std::nano;
15 using duration = std::chrono::nanoseconds;
16 using time_point = std::chrono::time_point<SteadyClock>;
17
18 static constexpr bool is_steady = true;
19
20 [[nodiscard]] static time_point Now() noexcept;
21};
22
23} // namespace Common
diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp
index ae07f2811..817e71d52 100644
--- a/src/common/wall_clock.cpp
+++ b/src/common/wall_clock.cpp
@@ -1,6 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/steady_clock.h"
4#include "common/uint128.h" 5#include "common/uint128.h"
5#include "common/wall_clock.h" 6#include "common/wall_clock.h"
6 7
@@ -11,45 +12,32 @@
11 12
12namespace Common { 13namespace Common {
13 14
14using base_timer = std::chrono::steady_clock;
15using base_time_point = std::chrono::time_point<base_timer>;
16
17class StandardWallClock final : public WallClock { 15class StandardWallClock final : public WallClock {
18public: 16public:
19 explicit StandardWallClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_) 17 explicit StandardWallClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_)
20 : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, false) { 18 : WallClock{emulated_cpu_frequency_, emulated_clock_frequency_, false},
21 start_time = base_timer::now(); 19 start_time{SteadyClock::Now()} {}
22 }
23 20
24 std::chrono::nanoseconds GetTimeNS() override { 21 std::chrono::nanoseconds GetTimeNS() override {
25 base_time_point current = base_timer::now(); 22 return SteadyClock::Now() - start_time;
26 auto elapsed = current - start_time;
27 return std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed);
28 } 23 }
29 24
30 std::chrono::microseconds GetTimeUS() override { 25 std::chrono::microseconds GetTimeUS() override {
31 base_time_point current = base_timer::now(); 26 return std::chrono::duration_cast<std::chrono::microseconds>(GetTimeNS());
32 auto elapsed = current - start_time;
33 return std::chrono::duration_cast<std::chrono::microseconds>(elapsed);
34 } 27 }
35 28
36 std::chrono::milliseconds GetTimeMS() override { 29 std::chrono::milliseconds GetTimeMS() override {
37 base_time_point current = base_timer::now(); 30 return std::chrono::duration_cast<std::chrono::milliseconds>(GetTimeNS());
38 auto elapsed = current - start_time;
39 return std::chrono::duration_cast<std::chrono::milliseconds>(elapsed);
40 } 31 }
41 32
42 u64 GetClockCycles() override { 33 u64 GetClockCycles() override {
43 std::chrono::nanoseconds time_now = GetTimeNS(); 34 const u128 temp = Common::Multiply64Into128(GetTimeNS().count(), emulated_clock_frequency);
44 const u128 temporary = 35 return Common::Divide128On32(temp, NS_RATIO).first;
45 Common::Multiply64Into128(time_now.count(), emulated_clock_frequency);
46 return Common::Divide128On32(temporary, 1000000000).first;
47 } 36 }
48 37
49 u64 GetCPUCycles() override { 38 u64 GetCPUCycles() override {
50 std::chrono::nanoseconds time_now = GetTimeNS(); 39 const u128 temp = Common::Multiply64Into128(GetTimeNS().count(), emulated_cpu_frequency);
51 const u128 temporary = Common::Multiply64Into128(time_now.count(), emulated_cpu_frequency); 40 return Common::Divide128On32(temp, NS_RATIO).first;
52 return Common::Divide128On32(temporary, 1000000000).first;
53 } 41 }
54 42
55 void Pause([[maybe_unused]] bool is_paused) override { 43 void Pause([[maybe_unused]] bool is_paused) override {
@@ -57,7 +45,7 @@ public:
57 } 45 }
58 46
59private: 47private:
60 base_time_point start_time; 48 SteadyClock::time_point start_time;
61}; 49};
62 50
63#ifdef ARCHITECTURE_x86_64 51#ifdef ARCHITECTURE_x86_64
@@ -93,4 +81,9 @@ std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency,
93 81
94#endif 82#endif
95 83
84std::unique_ptr<WallClock> CreateStandardWallClock(u64 emulated_cpu_frequency,
85 u64 emulated_clock_frequency) {
86 return std::make_unique<StandardWallClock>(emulated_cpu_frequency, emulated_clock_frequency);
87}
88
96} // namespace Common 89} // namespace Common
diff --git a/src/common/wall_clock.h b/src/common/wall_clock.h
index 828a523a8..157ec5eae 100644
--- a/src/common/wall_clock.h
+++ b/src/common/wall_clock.h
@@ -55,4 +55,7 @@ private:
55[[nodiscard]] std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency, 55[[nodiscard]] std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency,
56 u64 emulated_clock_frequency); 56 u64 emulated_clock_frequency);
57 57
58[[nodiscard]] std::unique_ptr<WallClock> CreateStandardWallClock(u64 emulated_cpu_frequency,
59 u64 emulated_clock_frequency);
60
58} // namespace Common 61} // namespace Common
diff --git a/src/common/windows/timer_resolution.cpp b/src/common/windows/timer_resolution.cpp
new file mode 100644
index 000000000..29c6e5c7e
--- /dev/null
+++ b/src/common/windows/timer_resolution.cpp
@@ -0,0 +1,109 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <windows.h>
5
6#include "common/windows/timer_resolution.h"
7
8extern "C" {
9// http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FTime%2FNtQueryTimerResolution.html
10NTSYSAPI LONG NTAPI NtQueryTimerResolution(PULONG MinimumResolution, PULONG MaximumResolution,
11 PULONG CurrentResolution);
12
13// http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FTime%2FNtSetTimerResolution.html
14NTSYSAPI LONG NTAPI NtSetTimerResolution(ULONG DesiredResolution, BOOLEAN SetResolution,
15 PULONG CurrentResolution);
16
17// http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FNT%20Objects%2FThread%2FNtDelayExecution.html
18NTSYSAPI LONG NTAPI NtDelayExecution(BOOLEAN Alertable, PLARGE_INTEGER DelayInterval);
19}
20
21// Defines for compatibility with older Windows 10 SDKs.
22
23#ifndef PROCESS_POWER_THROTTLING_EXECUTION_SPEED
24#define PROCESS_POWER_THROTTLING_EXECUTION_SPEED 0x1
25#endif
26#ifndef PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION
27#define PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION 0x4
28#endif
29
30namespace Common::Windows {
31
32namespace {
33
34using namespace std::chrono;
35
36constexpr nanoseconds ToNS(ULONG hundred_ns) {
37 return nanoseconds{hundred_ns * 100};
38}
39
40constexpr ULONG ToHundredNS(nanoseconds ns) {
41 return static_cast<ULONG>(ns.count()) / 100;
42}
43
44struct TimerResolution {
45 std::chrono::nanoseconds minimum;
46 std::chrono::nanoseconds maximum;
47 std::chrono::nanoseconds current;
48};
49
50TimerResolution GetTimerResolution() {
51 ULONG MinimumTimerResolution;
52 ULONG MaximumTimerResolution;
53 ULONG CurrentTimerResolution;
54 NtQueryTimerResolution(&MinimumTimerResolution, &MaximumTimerResolution,
55 &CurrentTimerResolution);
56 return {
57 .minimum{ToNS(MinimumTimerResolution)},
58 .maximum{ToNS(MaximumTimerResolution)},
59 .current{ToNS(CurrentTimerResolution)},
60 };
61}
62
63void SetHighQoS() {
64 // https://learn.microsoft.com/en-us/windows/win32/procthread/quality-of-service
65 PROCESS_POWER_THROTTLING_STATE PowerThrottling{
66 .Version{PROCESS_POWER_THROTTLING_CURRENT_VERSION},
67 .ControlMask{PROCESS_POWER_THROTTLING_EXECUTION_SPEED |
68 PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION},
69 .StateMask{},
70 };
71 SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, &PowerThrottling,
72 sizeof(PROCESS_POWER_THROTTLING_STATE));
73}
74
75} // Anonymous namespace
76
77nanoseconds GetMinimumTimerResolution() {
78 return GetTimerResolution().minimum;
79}
80
81nanoseconds GetMaximumTimerResolution() {
82 return GetTimerResolution().maximum;
83}
84
85nanoseconds GetCurrentTimerResolution() {
86 return GetTimerResolution().current;
87}
88
89nanoseconds SetCurrentTimerResolution(nanoseconds timer_resolution) {
90 // Set the timer resolution, and return the current timer resolution.
91 const auto DesiredTimerResolution = ToHundredNS(timer_resolution);
92 ULONG CurrentTimerResolution;
93 NtSetTimerResolution(DesiredTimerResolution, TRUE, &CurrentTimerResolution);
94 return ToNS(CurrentTimerResolution);
95}
96
97nanoseconds SetCurrentTimerResolutionToMaximum() {
98 SetHighQoS();
99 return SetCurrentTimerResolution(GetMaximumTimerResolution());
100}
101
102void SleepForOneTick() {
103 LARGE_INTEGER DelayInterval{
104 .QuadPart{-1},
105 };
106 NtDelayExecution(FALSE, &DelayInterval);
107}
108
109} // namespace Common::Windows
diff --git a/src/common/windows/timer_resolution.h b/src/common/windows/timer_resolution.h
new file mode 100644
index 000000000..e1e50a62d
--- /dev/null
+++ b/src/common/windows/timer_resolution.h
@@ -0,0 +1,38 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <chrono>
7
8namespace Common::Windows {
9
10/// Returns the minimum (least precise) supported timer resolution in nanoseconds.
11std::chrono::nanoseconds GetMinimumTimerResolution();
12
13/// Returns the maximum (most precise) supported timer resolution in nanoseconds.
14std::chrono::nanoseconds GetMaximumTimerResolution();
15
16/// Returns the current timer resolution in nanoseconds.
17std::chrono::nanoseconds GetCurrentTimerResolution();
18
19/**
20 * Sets the current timer resolution.
21 *
22 * @param timer_resolution Timer resolution in nanoseconds.
23 *
24 * @returns The current timer resolution.
25 */
26std::chrono::nanoseconds SetCurrentTimerResolution(std::chrono::nanoseconds timer_resolution);
27
28/**
29 * Sets the current timer resolution to the maximum supported timer resolution.
30 *
31 * @returns The current timer resolution.
32 */
33std::chrono::nanoseconds SetCurrentTimerResolutionToMaximum();
34
35/// Sleep for one tick of the current timer resolution.
36void SleepForOneTick();
37
38} // namespace Common::Windows
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp
index 8b08332ab..bc1a973b0 100644
--- a/src/common/x64/native_clock.cpp
+++ b/src/common/x64/native_clock.cpp
@@ -6,6 +6,7 @@
6#include <thread> 6#include <thread>
7 7
8#include "common/atomic_ops.h" 8#include "common/atomic_ops.h"
9#include "common/steady_clock.h"
9#include "common/uint128.h" 10#include "common/uint128.h"
10#include "common/x64/native_clock.h" 11#include "common/x64/native_clock.h"
11 12
@@ -39,6 +40,12 @@ static u64 FencedRDTSC() {
39} 40}
40#endif 41#endif
41 42
43template <u64 Nearest>
44static u64 RoundToNearest(u64 value) {
45 const auto mod = value % Nearest;
46 return mod >= (Nearest / 2) ? (value - mod + Nearest) : (value - mod);
47}
48
42u64 EstimateRDTSCFrequency() { 49u64 EstimateRDTSCFrequency() {
43 // Discard the first result measuring the rdtsc. 50 // Discard the first result measuring the rdtsc.
44 FencedRDTSC(); 51 FencedRDTSC();
@@ -46,18 +53,18 @@ u64 EstimateRDTSCFrequency() {
46 FencedRDTSC(); 53 FencedRDTSC();
47 54
48 // Get the current time. 55 // Get the current time.
49 const auto start_time = std::chrono::steady_clock::now(); 56 const auto start_time = Common::SteadyClock::Now();
50 const u64 tsc_start = FencedRDTSC(); 57 const u64 tsc_start = FencedRDTSC();
51 // Wait for 200 milliseconds. 58 // Wait for 250 milliseconds.
52 std::this_thread::sleep_for(std::chrono::milliseconds{200}); 59 std::this_thread::sleep_for(std::chrono::milliseconds{250});
53 const auto end_time = std::chrono::steady_clock::now(); 60 const auto end_time = Common::SteadyClock::Now();
54 const u64 tsc_end = FencedRDTSC(); 61 const u64 tsc_end = FencedRDTSC();
55 // Calculate differences. 62 // Calculate differences.
56 const u64 timer_diff = static_cast<u64>( 63 const u64 timer_diff = static_cast<u64>(
57 std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count()); 64 std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count());
58 const u64 tsc_diff = tsc_end - tsc_start; 65 const u64 tsc_diff = tsc_end - tsc_start;
59 const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff); 66 const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff);
60 return tsc_freq; 67 return RoundToNearest<1000>(tsc_freq);
61} 68}
62 69
63namespace X64 { 70namespace X64 {
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index ff5502d87..75e0c4f38 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -158,7 +158,6 @@ add_library(core STATIC
158 hid/motion_input.h 158 hid/motion_input.h
159 hle/api_version.h 159 hle/api_version.h
160 hle/ipc.h 160 hle/ipc.h
161 hle/ipc_helpers.h
162 hle/kernel/board/nintendo/nx/k_memory_layout.h 161 hle/kernel/board/nintendo/nx/k_memory_layout.h
163 hle/kernel/board/nintendo/nx/k_system_control.cpp 162 hle/kernel/board/nintendo/nx/k_system_control.cpp
164 hle/kernel/board/nintendo/nx/k_system_control.h 163 hle/kernel/board/nintendo/nx/k_system_control.h
@@ -168,8 +167,6 @@ add_library(core STATIC
168 hle/kernel/svc_results.h 167 hle/kernel/svc_results.h
169 hle/kernel/global_scheduler_context.cpp 168 hle/kernel/global_scheduler_context.cpp
170 hle/kernel/global_scheduler_context.h 169 hle/kernel/global_scheduler_context.h
171 hle/kernel/hle_ipc.cpp
172 hle/kernel/hle_ipc.h
173 hle/kernel/init/init_slab_setup.cpp 170 hle/kernel/init/init_slab_setup.cpp
174 hle/kernel/init/init_slab_setup.h 171 hle/kernel/init/init_slab_setup.h
175 hle/kernel/initial_process.h 172 hle/kernel/initial_process.h
@@ -293,8 +290,6 @@ add_library(core STATIC
293 hle/kernel/physical_memory.h 290 hle/kernel/physical_memory.h
294 hle/kernel/process_capability.cpp 291 hle/kernel/process_capability.cpp
295 hle/kernel/process_capability.h 292 hle/kernel/process_capability.h
296 hle/kernel/service_thread.cpp
297 hle/kernel/service_thread.h
298 hle/kernel/slab_helpers.h 293 hle/kernel/slab_helpers.h
299 hle/kernel/svc.cpp 294 hle/kernel/svc.cpp
300 hle/kernel/svc.h 295 hle/kernel/svc.h
@@ -459,7 +454,6 @@ add_library(core STATIC
459 hle/service/filesystem/fsp_srv.h 454 hle/service/filesystem/fsp_srv.h
460 hle/service/fgm/fgm.cpp 455 hle/service/fgm/fgm.cpp
461 hle/service/fgm/fgm.h 456 hle/service/fgm/fgm.h
462 hle/service/friend/errors.h
463 hle/service/friend/friend.cpp 457 hle/service/friend/friend.cpp
464 hle/service/friend/friend.h 458 hle/service/friend/friend.h
465 hle/service/friend/friend_interface.cpp 459 hle/service/friend/friend_interface.cpp
@@ -631,35 +625,35 @@ add_library(core STATIC
631 hle/service/nvdrv/nvdrv_interface.h 625 hle/service/nvdrv/nvdrv_interface.h
632 hle/service/nvdrv/nvmemp.cpp 626 hle/service/nvdrv/nvmemp.cpp
633 hle/service/nvdrv/nvmemp.h 627 hle/service/nvdrv/nvmemp.h
634 hle/service/nvflinger/binder.h 628 hle/service/nvnflinger/binder.h
635 hle/service/nvflinger/buffer_item.h 629 hle/service/nvnflinger/buffer_item.h
636 hle/service/nvflinger/buffer_item_consumer.cpp 630 hle/service/nvnflinger/buffer_item_consumer.cpp
637 hle/service/nvflinger/buffer_item_consumer.h 631 hle/service/nvnflinger/buffer_item_consumer.h
638 hle/service/nvflinger/buffer_queue_consumer.cpp 632 hle/service/nvnflinger/buffer_queue_consumer.cpp
639 hle/service/nvflinger/buffer_queue_consumer.h 633 hle/service/nvnflinger/buffer_queue_consumer.h
640 hle/service/nvflinger/buffer_queue_core.cpp 634 hle/service/nvnflinger/buffer_queue_core.cpp
641 hle/service/nvflinger/buffer_queue_core.h 635 hle/service/nvnflinger/buffer_queue_core.h
642 hle/service/nvflinger/buffer_queue_defs.h 636 hle/service/nvnflinger/buffer_queue_defs.h
643 hle/service/nvflinger/buffer_queue_producer.cpp 637 hle/service/nvnflinger/buffer_queue_producer.cpp
644 hle/service/nvflinger/buffer_queue_producer.h 638 hle/service/nvnflinger/buffer_queue_producer.h
645 hle/service/nvflinger/buffer_slot.h 639 hle/service/nvnflinger/buffer_slot.h
646 hle/service/nvflinger/buffer_transform_flags.h 640 hle/service/nvnflinger/buffer_transform_flags.h
647 hle/service/nvflinger/consumer_base.cpp 641 hle/service/nvnflinger/consumer_base.cpp
648 hle/service/nvflinger/consumer_base.h 642 hle/service/nvnflinger/consumer_base.h
649 hle/service/nvflinger/consumer_listener.h 643 hle/service/nvnflinger/consumer_listener.h
650 hle/service/nvflinger/graphic_buffer_producer.cpp 644 hle/service/nvnflinger/graphic_buffer_producer.cpp
651 hle/service/nvflinger/graphic_buffer_producer.h 645 hle/service/nvnflinger/graphic_buffer_producer.h
652 hle/service/nvflinger/hos_binder_driver_server.cpp 646 hle/service/nvnflinger/hos_binder_driver_server.cpp
653 hle/service/nvflinger/hos_binder_driver_server.h 647 hle/service/nvnflinger/hos_binder_driver_server.h
654 hle/service/nvflinger/nvflinger.cpp 648 hle/service/nvnflinger/nvnflinger.cpp
655 hle/service/nvflinger/nvflinger.h 649 hle/service/nvnflinger/nvnflinger.h
656 hle/service/nvflinger/parcel.h 650 hle/service/nvnflinger/parcel.h
657 hle/service/nvflinger/pixel_format.h 651 hle/service/nvnflinger/pixel_format.h
658 hle/service/nvflinger/producer_listener.h 652 hle/service/nvnflinger/producer_listener.h
659 hle/service/nvflinger/status.h 653 hle/service/nvnflinger/status.h
660 hle/service/nvflinger/ui/fence.h 654 hle/service/nvnflinger/ui/fence.h
661 hle/service/nvflinger/ui/graphic_buffer.h 655 hle/service/nvnflinger/ui/graphic_buffer.h
662 hle/service/nvflinger/window.h 656 hle/service/nvnflinger/window.h
663 hle/service/olsc/olsc.cpp 657 hle/service/olsc/olsc.cpp
664 hle/service/olsc/olsc.h 658 hle/service/olsc/olsc.h
665 hle/service/pcie/pcie.cpp 659 hle/service/pcie/pcie.cpp
@@ -682,8 +676,15 @@ add_library(core STATIC
682 hle/service/ptm/ptm.h 676 hle/service/ptm/ptm.h
683 hle/service/ptm/ts.cpp 677 hle/service/ptm/ts.cpp
684 hle/service/ptm/ts.h 678 hle/service/ptm/ts.h
679 hle/service/hle_ipc.cpp
680 hle/service/hle_ipc.h
681 hle/service/ipc_helpers.h
685 hle/service/kernel_helpers.cpp 682 hle/service/kernel_helpers.cpp
686 hle/service/kernel_helpers.h 683 hle/service/kernel_helpers.h
684 hle/service/mutex.cpp
685 hle/service/mutex.h
686 hle/service/server_manager.cpp
687 hle/service/server_manager.h
687 hle/service/service.cpp 688 hle/service/service.cpp
688 hle/service/service.h 689 hle/service/service.h
689 hle/service/set/set.cpp 690 hle/service/set/set.cpp
@@ -832,7 +833,7 @@ endif()
832create_target_directory_groups(core) 833create_target_directory_groups(core)
833 834
834target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core) 835target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core)
835target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::opus) 836target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::opus)
836if (MINGW) 837if (MINGW)
837 target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY}) 838 target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
838endif() 839endif()
@@ -861,3 +862,7 @@ endif()
861if (YUZU_USE_PRECOMPILED_HEADERS) 862if (YUZU_USE_PRECOMPILED_HEADERS)
862 target_precompile_headers(core PRIVATE precompiled_headers.h) 863 target_precompile_headers(core PRIVATE precompiled_headers.h)
863endif() 864endif()
865
866if (YUZU_ENABLE_LTO)
867 set_property(TARGET core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
868endif()
diff --git a/src/core/constants.cpp b/src/core/constants.cpp
index 4430173ef..760dc5f23 100644
--- a/src/core/constants.cpp
+++ b/src/core/constants.cpp
@@ -4,13 +4,24 @@
4#include "core/constants.h" 4#include "core/constants.h"
5 5
6namespace Core::Constants { 6namespace Core::Constants {
7const std::array<u8, 107> ACCOUNT_BACKUP_JPEG{{ 7const std::array<u8, 287> ACCOUNT_BACKUP_JPEG{{
8 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 8 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48,
9 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x06, 0x06, 0x05, 9 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x06, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06,
10 0x06, 0x09, 0x08, 0x0a, 0x0a, 0x09, 0x08, 0x09, 0x09, 0x0a, 0x0c, 0x0f, 0x0c, 0x0a, 0x0b, 0x0e, 10 0x05, 0x05, 0x06, 0x09, 0x06, 0x05, 0x06, 0x09, 0x0b, 0x08, 0x06, 0x06, 0x08, 0x0b, 0x0c, 0x0a,
11 0x0b, 0x09, 0x09, 0x0d, 0x11, 0x0d, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x10, 0x0a, 0x0c, 0x12, 0x13, 11 0x0a, 0x0b, 0x0a, 0x0a, 0x0c, 0x10, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x10, 0x0c, 0x0e, 0x0f,
12 0x12, 0x10, 0x13, 0x0f, 0x10, 0x10, 0x10, 0xff, 0xc9, 0x00, 0x0b, 0x08, 0x00, 0x01, 0x00, 0x01, 12 0x10, 0x0f, 0x0e, 0x0c, 0x13, 0x13, 0x14, 0x14, 0x13, 0x13, 0x1c, 0x1b, 0x1b, 0x1b, 0x1c, 0x20,
13 0x01, 0x01, 0x11, 0x00, 0xff, 0xcc, 0x00, 0x06, 0x00, 0x10, 0x10, 0x05, 0xff, 0xda, 0x00, 0x08, 13 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x07, 0x07,
14 0x01, 0x01, 0x00, 0x00, 0x3f, 0x00, 0xd2, 0xcf, 0x20, 0xff, 0xd9, 14 0x07, 0x0d, 0x0c, 0x0d, 0x18, 0x10, 0x10, 0x18, 0x1a, 0x15, 0x11, 0x15, 0x1a, 0x20, 0x20, 0x20,
15 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
16 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
17 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0xc0,
18 0x00, 0x11, 0x08, 0x00, 0x20, 0x00, 0x20, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11,
19 0x01, 0xff, 0xc4, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00,
21 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00,
22 0x14, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00,
25 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd9,
15}}; 26}};
16} 27}
diff --git a/src/core/constants.h b/src/core/constants.h
index f916ce0b6..f1f67d3b8 100644
--- a/src/core/constants.h
+++ b/src/core/constants.h
@@ -12,6 +12,6 @@
12namespace Core::Constants { 12namespace Core::Constants {
13 13
14// ACC Service - Blank JPEG used as user icon in absentia of real one. 14// ACC Service - Blank JPEG used as user icon in absentia of real one.
15extern const std::array<u8, 107> ACCOUNT_BACKUP_JPEG; 15extern const std::array<u8, 287> ACCOUNT_BACKUP_JPEG;
16 16
17} // namespace Core::Constants 17} // namespace Core::Constants
diff --git a/src/core/core.cpp b/src/core/core.cpp
index fb9b25d12..4a1372d15 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -380,9 +380,7 @@ struct System::Impl {
380 gpu_core->NotifyShutdown(); 380 gpu_core->NotifyShutdown();
381 } 381 }
382 382
383 kernel.ShutdownCores(); 383 kernel.SuspendApplication(true);
384 cpu_manager.Shutdown();
385 debugger.reset();
386 if (services) { 384 if (services) {
387 services->KillNVNFlinger(); 385 services->KillNVNFlinger();
388 } 386 }
@@ -398,6 +396,9 @@ struct System::Impl {
398 gpu_core.reset(); 396 gpu_core.reset();
399 host1x_core.reset(); 397 host1x_core.reset();
400 perf_stats.reset(); 398 perf_stats.reset();
399 kernel.ShutdownCores();
400 cpu_manager.Shutdown();
401 debugger.reset();
401 kernel.Shutdown(); 402 kernel.Shutdown();
402 memory.Reset(); 403 memory.Reset();
403 404
@@ -938,6 +939,10 @@ const Network::RoomNetwork& System::GetRoomNetwork() const {
938 return impl->room_network; 939 return impl->room_network;
939} 940}
940 941
942void System::RunServer(std::unique_ptr<Service::ServerManager>&& server_manager) {
943 return impl->kernel.RunServer(std::move(server_manager));
944}
945
941void System::RegisterExecuteProgramCallback(ExecuteProgramCallback&& callback) { 946void System::RegisterExecuteProgramCallback(ExecuteProgramCallback&& callback) {
942 impl->execute_program_callback = std::move(callback); 947 impl->execute_program_callback = std::move(callback);
943} 948}
diff --git a/src/core/core.h b/src/core/core.h
index 0042ac170..91e78672e 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -61,6 +61,8 @@ namespace Glue {
61class ARPManager; 61class ARPManager;
62} 62}
63 63
64class ServerManager;
65
64namespace SM { 66namespace SM {
65class ServiceManager; 67class ServiceManager;
66} // namespace SM 68} // namespace SM
@@ -417,6 +419,9 @@ public:
417 /// Tells if the system debugger is enabled. 419 /// Tells if the system debugger is enabled.
418 [[nodiscard]] bool DebuggerEnabled() const; 420 [[nodiscard]] bool DebuggerEnabled() const;
419 421
422 /// Runs a server instance until shutdown.
423 void RunServer(std::unique_ptr<Service::ServerManager>&& server_manager);
424
420 /// Type used for the frontend to designate a callback for System to re-launch the application 425 /// Type used for the frontend to designate a callback for System to re-launch the application
421 /// using a specified program index. 426 /// using a specified program index.
422 using ExecuteProgramCallback = std::function<void(std::size_t)>; 427 using ExecuteProgramCallback = std::function<void(std::size_t)>;
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 3a63b52e3..742cfb996 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -6,6 +6,10 @@
6#include <string> 6#include <string>
7#include <tuple> 7#include <tuple>
8 8
9#ifdef _WIN32
10#include "common/windows/timer_resolution.h"
11#endif
12
9#include "common/microprofile.h" 13#include "common/microprofile.h"
10#include "core/core_timing.h" 14#include "core/core_timing.h"
11#include "core/core_timing_util.h" 15#include "core/core_timing_util.h"
@@ -38,7 +42,8 @@ struct CoreTiming::Event {
38}; 42};
39 43
40CoreTiming::CoreTiming() 44CoreTiming::CoreTiming()
41 : clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {} 45 : cpu_clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)},
46 event_clock{Common::CreateStandardWallClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {}
42 47
43CoreTiming::~CoreTiming() { 48CoreTiming::~CoreTiming() {
44 Reset(); 49 Reset();
@@ -185,15 +190,15 @@ void CoreTiming::ResetTicks() {
185} 190}
186 191
187u64 CoreTiming::GetCPUTicks() const { 192u64 CoreTiming::GetCPUTicks() const {
188 if (is_multicore) { 193 if (is_multicore) [[likely]] {
189 return clock->GetCPUCycles(); 194 return cpu_clock->GetCPUCycles();
190 } 195 }
191 return ticks; 196 return ticks;
192} 197}
193 198
194u64 CoreTiming::GetClockTicks() const { 199u64 CoreTiming::GetClockTicks() const {
195 if (is_multicore) { 200 if (is_multicore) [[likely]] {
196 return clock->GetClockCycles(); 201 return cpu_clock->GetClockCycles();
197 } 202 }
198 return CpuCyclesToClockCycles(ticks); 203 return CpuCyclesToClockCycles(ticks);
199} 204}
@@ -252,21 +257,20 @@ void CoreTiming::ThreadLoop() {
252 const auto next_time = Advance(); 257 const auto next_time = Advance();
253 if (next_time) { 258 if (next_time) {
254 // There are more events left in the queue, wait until the next event. 259 // There are more events left in the queue, wait until the next event.
255 const auto wait_time = *next_time - GetGlobalTimeNs().count(); 260 auto wait_time = *next_time - GetGlobalTimeNs().count();
256 if (wait_time > 0) { 261 if (wait_time > 0) {
257#ifdef _WIN32 262#ifdef _WIN32
258 // Assume a timer resolution of 1ms. 263 const auto timer_resolution_ns =
259 static constexpr s64 TimerResolutionNS = 1000000; 264 Common::Windows::GetCurrentTimerResolution().count();
260 265
261 // Sleep in discrete intervals of the timer resolution, and spin the rest. 266 while (!paused && !event.IsSet() && wait_time > 0) {
262 const auto sleep_time = wait_time - (wait_time % TimerResolutionNS); 267 wait_time = *next_time - GetGlobalTimeNs().count();
263 if (sleep_time > 0) {
264 event.WaitFor(std::chrono::nanoseconds(sleep_time));
265 }
266 268
267 while (!paused && !event.IsSet() && GetGlobalTimeNs().count() < *next_time) { 269 if (wait_time >= timer_resolution_ns) {
268 // Yield to reduce thread starvation. 270 Common::Windows::SleepForOneTick();
269 std::this_thread::yield(); 271 } else {
272 std::this_thread::yield();
273 }
270 } 274 }
271 275
272 if (event.IsSet()) { 276 if (event.IsSet()) {
@@ -285,9 +289,9 @@ void CoreTiming::ThreadLoop() {
285 } 289 }
286 290
287 paused_set = true; 291 paused_set = true;
288 clock->Pause(true); 292 event_clock->Pause(true);
289 pause_event.Wait(); 293 pause_event.Wait();
290 clock->Pause(false); 294 event_clock->Pause(false);
291 } 295 }
292} 296}
293 297
@@ -303,16 +307,23 @@ void CoreTiming::Reset() {
303 has_started = false; 307 has_started = false;
304} 308}
305 309
310std::chrono::nanoseconds CoreTiming::GetCPUTimeNs() const {
311 if (is_multicore) [[likely]] {
312 return cpu_clock->GetTimeNS();
313 }
314 return CyclesToNs(ticks);
315}
316
306std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const { 317std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const {
307 if (is_multicore) { 318 if (is_multicore) [[likely]] {
308 return clock->GetTimeNS(); 319 return event_clock->GetTimeNS();
309 } 320 }
310 return CyclesToNs(ticks); 321 return CyclesToNs(ticks);
311} 322}
312 323
313std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const { 324std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const {
314 if (is_multicore) { 325 if (is_multicore) [[likely]] {
315 return clock->GetTimeUS(); 326 return event_clock->GetTimeUS();
316 } 327 }
317 return CyclesToUs(ticks); 328 return CyclesToUs(ticks);
318} 329}
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index da366637b..4b89c0c39 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -122,6 +122,9 @@ public:
122 /// Returns current time in emulated in Clock cycles 122 /// Returns current time in emulated in Clock cycles
123 u64 GetClockTicks() const; 123 u64 GetClockTicks() const;
124 124
125 /// Returns current time in nanoseconds.
126 std::chrono::nanoseconds GetCPUTimeNs() const;
127
125 /// Returns current time in microseconds. 128 /// Returns current time in microseconds.
126 std::chrono::microseconds GetGlobalTimeUs() const; 129 std::chrono::microseconds GetGlobalTimeUs() const;
127 130
@@ -139,7 +142,8 @@ private:
139 142
140 void Reset(); 143 void Reset();
141 144
142 std::unique_ptr<Common::WallClock> clock; 145 std::unique_ptr<Common::WallClock> cpu_clock;
146 std::unique_ptr<Common::WallClock> event_clock;
143 147
144 s64 global_timer = 0; 148 s64 global_timer = 0;
145 149
diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp
index a9675df76..a1589fecb 100644
--- a/src/core/debugger/debugger.cpp
+++ b/src/core/debugger/debugger.cpp
@@ -16,6 +16,7 @@
16#include "core/debugger/debugger_interface.h" 16#include "core/debugger/debugger_interface.h"
17#include "core/debugger/gdbstub.h" 17#include "core/debugger/gdbstub.h"
18#include "core/hle/kernel/global_scheduler_context.h" 18#include "core/hle/kernel/global_scheduler_context.h"
19#include "core/hle/kernel/k_process.h"
19#include "core/hle/kernel/k_scheduler.h" 20#include "core/hle/kernel/k_scheduler.h"
20 21
21template <typename Readable, typename Buffer, typename Callback> 22template <typename Readable, typename Buffer, typename Callback>
@@ -284,12 +285,12 @@ private:
284 void UpdateActiveThread() { 285 void UpdateActiveThread() {
285 const auto& threads{ThreadList()}; 286 const auto& threads{ThreadList()};
286 if (std::find(threads.begin(), threads.end(), state->active_thread) == threads.end()) { 287 if (std::find(threads.begin(), threads.end(), state->active_thread) == threads.end()) {
287 state->active_thread = threads[0]; 288 state->active_thread = threads.front();
288 } 289 }
289 } 290 }
290 291
291 const std::vector<Kernel::KThread*>& ThreadList() { 292 const std::list<Kernel::KThread*>& ThreadList() {
292 return system.GlobalSchedulerContext().GetThreadList(); 293 return system.ApplicationProcess()->GetThreadList();
293 } 294 }
294 295
295private: 296private:
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp
index 945ec528e..18afe97e1 100644
--- a/src/core/debugger/gdbstub.cpp
+++ b/src/core/debugger/gdbstub.cpp
@@ -573,7 +573,7 @@ void GDBStub::HandleQuery(std::string_view command) {
573 SendReply(PaginateBuffer(buffer, command.substr(21))); 573 SendReply(PaginateBuffer(buffer, command.substr(21)));
574 } else if (command.starts_with("fThreadInfo")) { 574 } else if (command.starts_with("fThreadInfo")) {
575 // beginning of list 575 // beginning of list
576 const auto& threads = system.GlobalSchedulerContext().GetThreadList(); 576 const auto& threads = system.ApplicationProcess()->GetThreadList();
577 std::vector<std::string> thread_ids; 577 std::vector<std::string> thread_ids;
578 for (const auto& thread : threads) { 578 for (const auto& thread : threads) {
579 thread_ids.push_back(fmt::format("{:x}", thread->GetThreadID())); 579 thread_ids.push_back(fmt::format("{:x}", thread->GetThreadID()));
@@ -587,7 +587,7 @@ void GDBStub::HandleQuery(std::string_view command) {
587 buffer += R"(<?xml version="1.0"?>)"; 587 buffer += R"(<?xml version="1.0"?>)";
588 buffer += "<threads>"; 588 buffer += "<threads>";
589 589
590 const auto& threads = system.GlobalSchedulerContext().GetThreadList(); 590 const auto& threads = system.ApplicationProcess()->GetThreadList();
591 for (const auto* thread : threads) { 591 for (const auto* thread : threads) {
592 auto thread_name{GetThreadName(system, thread)}; 592 auto thread_name{GetThreadName(system, thread)};
593 if (!thread_name) { 593 if (!thread_name) {
@@ -817,7 +817,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
817} 817}
818 818
819Kernel::KThread* GDBStub::GetThreadByID(u64 thread_id) { 819Kernel::KThread* GDBStub::GetThreadByID(u64 thread_id) {
820 const auto& threads{system.GlobalSchedulerContext().GetThreadList()}; 820 const auto& threads{system.ApplicationProcess()->GetThreadList()};
821 for (auto* thread : threads) { 821 for (auto* thread : threads) {
822 if (thread->GetThreadID() == thread_id) { 822 if (thread->GetThreadID() == thread_id) {
823 return thread; 823 return thread;
diff --git a/src/core/hardware_properties.h b/src/core/hardware_properties.h
index 45567b840..191c28bb4 100644
--- a/src/core/hardware_properties.h
+++ b/src/core/hardware_properties.h
@@ -13,11 +13,9 @@ namespace Core {
13 13
14namespace Hardware { 14namespace Hardware {
15 15
16// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz 16constexpr u64 BASE_CLOCK_RATE = 1'020'000'000; // Default CPU Frequency = 1020 MHz
17// The exact value used is of course unverified. 17constexpr u64 CNTFREQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz
18constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch cpu frequency is 1020MHz un/docked 18constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores
19constexpr u64 CNTFREQ = 19200000; // Switch's hardware clock speed
20constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores
21 19
22// Virtual to Physical core map. 20// Virtual to Physical core map.
23constexpr std::array<s32, Common::BitSize<u64>()> VirtualToPhysicalCoreMap{ 21constexpr std::array<s32, Common::BitSize<u64>()> VirtualToPhysicalCoreMap{
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
index c10b7bf30..5b8a248c8 100644
--- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
+++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
@@ -14,9 +14,12 @@ namespace Kernel::Board::Nintendo::Nx {
14 14
15namespace impl { 15namespace impl {
16 16
17constexpr const std::size_t RequiredNonSecureSystemMemorySizeVi = 0x2238 * 4 * 1024; 17using namespace Common::Literals;
18constexpr const std::size_t RequiredNonSecureSystemMemorySizeNvservices = 0x710 * 4 * 1024; 18
19constexpr const std::size_t RequiredNonSecureSystemMemorySizeMisc = 0x80 * 4 * 1024; 19constexpr const std::size_t RequiredNonSecureSystemMemorySizeVi = 0x2280 * 4_KiB;
20constexpr const std::size_t RequiredNonSecureSystemMemorySizeViFatal = 0x200 * 4_KiB;
21constexpr const std::size_t RequiredNonSecureSystemMemorySizeNvservices = 0x704 * 4_KiB;
22constexpr const std::size_t RequiredNonSecureSystemMemorySizeMisc = 0x80 * 4_KiB;
20 23
21} // namespace impl 24} // namespace impl
22 25
@@ -24,6 +27,9 @@ constexpr const std::size_t RequiredNonSecureSystemMemorySize =
24 impl::RequiredNonSecureSystemMemorySizeVi + impl::RequiredNonSecureSystemMemorySizeNvservices + 27 impl::RequiredNonSecureSystemMemorySizeVi + impl::RequiredNonSecureSystemMemorySizeNvservices +
25 impl::RequiredNonSecureSystemMemorySizeMisc; 28 impl::RequiredNonSecureSystemMemorySizeMisc;
26 29
30constexpr const std::size_t RequiredNonSecureSystemMemorySizeWithFatal =
31 RequiredNonSecureSystemMemorySize + impl::RequiredNonSecureSystemMemorySizeViFatal;
32
27namespace { 33namespace {
28 34
29using namespace Common::Literals; 35using namespace Common::Literals;
@@ -120,10 +126,13 @@ size_t KSystemControl::Init::GetAppletPoolSize() {
120 126
121size_t KSystemControl::Init::GetMinimumNonSecureSystemPoolSize() { 127size_t KSystemControl::Init::GetMinimumNonSecureSystemPoolSize() {
122 // Verify that our minimum is at least as large as Nintendo's. 128 // Verify that our minimum is at least as large as Nintendo's.
123 constexpr size_t MinimumSize = RequiredNonSecureSystemMemorySize; 129 constexpr size_t MinimumSizeWithFatal = RequiredNonSecureSystemMemorySizeWithFatal;
124 static_assert(MinimumSize >= 0x29C8000); 130 static_assert(MinimumSizeWithFatal >= 0x2C04000);
131
132 constexpr size_t MinimumSizeWithoutFatal = RequiredNonSecureSystemMemorySize;
133 static_assert(MinimumSizeWithoutFatal >= 0x2A00000);
125 134
126 return MinimumSize; 135 return MinimumSizeWithFatal;
127} 136}
128 137
129namespace { 138namespace {
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp
index abdb5639f..5e4090e2b 100644
--- a/src/core/hle/kernel/init/init_slab_setup.cpp
+++ b/src/core/hle/kernel/init/init_slab_setup.cpp
@@ -33,6 +33,9 @@
33 33
34namespace Kernel::Init { 34namespace Kernel::Init {
35 35
36// For macro convenience.
37using KThreadLockInfo = KThread::LockWithPriorityInheritanceInfo;
38
36#define SLAB_COUNT(CLASS) kernel.SlabResourceCounts().num_##CLASS 39#define SLAB_COUNT(CLASS) kernel.SlabResourceCounts().num_##CLASS
37 40
38#define FOREACH_SLAB_TYPE(HANDLER, ...) \ 41#define FOREACH_SLAB_TYPE(HANDLER, ...) \
@@ -54,7 +57,8 @@ namespace Kernel::Init {
54 HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) \ 57 HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) \
55 HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__) \ 58 HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
56 HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__) \ 59 HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
57 HANDLER(KSecureSystemResource, (SLAB_COUNT(KProcess)), ##__VA_ARGS__) 60 HANDLER(KSecureSystemResource, (SLAB_COUNT(KProcess)), ##__VA_ARGS__) \
61 HANDLER(KThreadLockInfo, (SLAB_COUNT(KThread)), ##__VA_ARGS__)
58 62
59namespace { 63namespace {
60 64
@@ -131,7 +135,7 @@ VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAd
131} 135}
132 136
133size_t CalculateSlabHeapGapSize() { 137size_t CalculateSlabHeapGapSize() {
134 constexpr size_t KernelSlabHeapGapSize = 2_MiB - 320_KiB; 138 constexpr size_t KernelSlabHeapGapSize = 2_MiB - 356_KiB;
135 static_assert(KernelSlabHeapGapSize <= KernelSlabHeapGapsSizeMax); 139 static_assert(KernelSlabHeapGapSize <= KernelSlabHeapGapsSizeMax);
136 return KernelSlabHeapGapSize; 140 return KernelSlabHeapGapSize;
137} 141}
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp
index a442a3b98..fb86451ea 100644
--- a/src/core/hle/kernel/k_address_arbiter.cpp
+++ b/src/core/hle/kernel/k_address_arbiter.cpp
@@ -29,7 +29,9 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu
29 auto& monitor = system.Monitor(); 29 auto& monitor = system.Monitor();
30 const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); 30 const auto current_core = system.Kernel().CurrentPhysicalCoreIndex();
31 31
32 // TODO(bunnei): We should disable interrupts here via KScopedInterruptDisable. 32 // NOTE: If scheduler lock is not held here, interrupt disable is required.
33 // KScopedInterruptDisable di;
34
33 // TODO(bunnei): We should call CanAccessAtomic(..) here. 35 // TODO(bunnei): We should call CanAccessAtomic(..) here.
34 36
35 // Load the value from the address. 37 // Load the value from the address.
@@ -59,7 +61,9 @@ bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32
59 auto& monitor = system.Monitor(); 61 auto& monitor = system.Monitor();
60 const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); 62 const auto current_core = system.Kernel().CurrentPhysicalCoreIndex();
61 63
62 // TODO(bunnei): We should disable interrupts here via KScopedInterruptDisable. 64 // NOTE: If scheduler lock is not held here, interrupt disable is required.
65 // KScopedInterruptDisable di;
66
63 // TODO(bunnei): We should call CanAccessAtomic(..) here. 67 // TODO(bunnei): We should call CanAccessAtomic(..) here.
64 68
65 // Load the value from the address. 69 // Load the value from the address.
diff --git a/src/core/hle/kernel/k_address_space_info.cpp b/src/core/hle/kernel/k_address_space_info.cpp
index 3e612a207..c36eb5dc4 100644
--- a/src/core/hle/kernel/k_address_space_info.cpp
+++ b/src/core/hle/kernel/k_address_space_info.cpp
@@ -23,86 +23,33 @@ constexpr std::array<KAddressSpaceInfo, 13> AddressSpaceInfos{{
23 { .bit_width = 32, .address = Size_Invalid, .size = 1_GiB , .type = KAddressSpaceInfo::Type::Heap, }, 23 { .bit_width = 32, .address = Size_Invalid, .size = 1_GiB , .type = KAddressSpaceInfo::Type::Heap, },
24 { .bit_width = 36, .address = 128_MiB , .size = 2_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::MapSmall, }, 24 { .bit_width = 36, .address = 128_MiB , .size = 2_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::MapSmall, },
25 { .bit_width = 36, .address = 2_GiB , .size = 64_GiB - 2_GiB , .type = KAddressSpaceInfo::Type::MapLarge, }, 25 { .bit_width = 36, .address = 2_GiB , .size = 64_GiB - 2_GiB , .type = KAddressSpaceInfo::Type::MapLarge, },
26 { .bit_width = 36, .address = Size_Invalid, .size = 6_GiB , .type = KAddressSpaceInfo::Type::Heap, }, 26 { .bit_width = 36, .address = Size_Invalid, .size = 8_GiB , .type = KAddressSpaceInfo::Type::Heap, },
27 { .bit_width = 36, .address = Size_Invalid, .size = 6_GiB , .type = KAddressSpaceInfo::Type::Alias, }, 27 { .bit_width = 36, .address = Size_Invalid, .size = 6_GiB , .type = KAddressSpaceInfo::Type::Alias, },
28 { .bit_width = 39, .address = 128_MiB , .size = 512_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::Map39Bit, }, 28 { .bit_width = 39, .address = 128_MiB , .size = 512_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::Map39Bit, },
29 { .bit_width = 39, .address = Size_Invalid, .size = 64_GiB , .type = KAddressSpaceInfo::Type::MapSmall }, 29 { .bit_width = 39, .address = Size_Invalid, .size = 64_GiB , .type = KAddressSpaceInfo::Type::MapSmall },
30 { .bit_width = 39, .address = Size_Invalid, .size = 6_GiB , .type = KAddressSpaceInfo::Type::Heap, }, 30 { .bit_width = 39, .address = Size_Invalid, .size = 8_GiB , .type = KAddressSpaceInfo::Type::Heap, },
31 { .bit_width = 39, .address = Size_Invalid, .size = 64_GiB , .type = KAddressSpaceInfo::Type::Alias, }, 31 { .bit_width = 39, .address = Size_Invalid, .size = 64_GiB , .type = KAddressSpaceInfo::Type::Alias, },
32 { .bit_width = 39, .address = Size_Invalid, .size = 2_GiB , .type = KAddressSpaceInfo::Type::Stack, }, 32 { .bit_width = 39, .address = Size_Invalid, .size = 2_GiB , .type = KAddressSpaceInfo::Type::Stack, },
33}}; 33}};
34// clang-format on 34// clang-format on
35 35
36constexpr bool IsAllowedIndexForAddress(std::size_t index) { 36const KAddressSpaceInfo& GetAddressSpaceInfo(size_t width, KAddressSpaceInfo::Type type) {
37 return index < AddressSpaceInfos.size() && AddressSpaceInfos[index].address != Size_Invalid; 37 for (auto& info : AddressSpaceInfos) {
38} 38 if (info.bit_width == width && info.type == type) {
39 39 return info;
40using IndexArray = 40 }
41 std::array<std::size_t, static_cast<std::size_t>(KAddressSpaceInfo::Type::Count)>; 41 }
42 42 UNREACHABLE_MSG("Could not find AddressSpaceInfo");
43constexpr IndexArray AddressSpaceIndices32Bit{
44 0, 1, 0, 2, 0, 3,
45};
46
47constexpr IndexArray AddressSpaceIndices36Bit{
48 4, 5, 4, 6, 4, 7,
49};
50
51constexpr IndexArray AddressSpaceIndices39Bit{
52 9, 8, 8, 10, 12, 11,
53};
54
55constexpr bool IsAllowed32BitType(KAddressSpaceInfo::Type type) {
56 return type < KAddressSpaceInfo::Type::Count && type != KAddressSpaceInfo::Type::Map39Bit &&
57 type != KAddressSpaceInfo::Type::Stack;
58}
59
60constexpr bool IsAllowed36BitType(KAddressSpaceInfo::Type type) {
61 return type < KAddressSpaceInfo::Type::Count && type != KAddressSpaceInfo::Type::Map39Bit &&
62 type != KAddressSpaceInfo::Type::Stack;
63}
64
65constexpr bool IsAllowed39BitType(KAddressSpaceInfo::Type type) {
66 return type < KAddressSpaceInfo::Type::Count && type != KAddressSpaceInfo::Type::MapLarge;
67} 43}
68 44
69} // namespace 45} // namespace
70 46
71u64 KAddressSpaceInfo::GetAddressSpaceStart(std::size_t width, Type type) { 47std::size_t KAddressSpaceInfo::GetAddressSpaceStart(size_t width, KAddressSpaceInfo::Type type) {
72 const std::size_t index{static_cast<std::size_t>(type)}; 48 return GetAddressSpaceInfo(width, type).address;
73 switch (width) {
74 case 32:
75 ASSERT(IsAllowed32BitType(type));
76 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices32Bit[index]));
77 return AddressSpaceInfos[AddressSpaceIndices32Bit[index]].address;
78 case 36:
79 ASSERT(IsAllowed36BitType(type));
80 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices36Bit[index]));
81 return AddressSpaceInfos[AddressSpaceIndices36Bit[index]].address;
82 case 39:
83 ASSERT(IsAllowed39BitType(type));
84 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices39Bit[index]));
85 return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].address;
86 }
87 ASSERT(false);
88 return 0;
89} 49}
90 50
91std::size_t KAddressSpaceInfo::GetAddressSpaceSize(std::size_t width, Type type) { 51std::size_t KAddressSpaceInfo::GetAddressSpaceSize(size_t width, KAddressSpaceInfo::Type type) {
92 const std::size_t index{static_cast<std::size_t>(type)}; 52 return GetAddressSpaceInfo(width, type).size;
93 switch (width) {
94 case 32:
95 ASSERT(IsAllowed32BitType(type));
96 return AddressSpaceInfos[AddressSpaceIndices32Bit[index]].size;
97 case 36:
98 ASSERT(IsAllowed36BitType(type));
99 return AddressSpaceInfos[AddressSpaceIndices36Bit[index]].size;
100 case 39:
101 ASSERT(IsAllowed39BitType(type));
102 return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].size;
103 }
104 ASSERT(false);
105 return 0;
106} 53}
107 54
108} // namespace Kernel 55} // namespace Kernel
diff --git a/src/core/hle/kernel/k_address_space_info.h b/src/core/hle/kernel/k_address_space_info.h
index 69e9d77f2..9a26f6b90 100644
--- a/src/core/hle/kernel/k_address_space_info.h
+++ b/src/core/hle/kernel/k_address_space_info.h
@@ -18,7 +18,7 @@ struct KAddressSpaceInfo final {
18 Count, 18 Count,
19 }; 19 };
20 20
21 static u64 GetAddressSpaceStart(std::size_t width, Type type); 21 static std::size_t GetAddressSpaceStart(std::size_t width, Type type);
22 static std::size_t GetAddressSpaceSize(std::size_t width, Type type); 22 static std::size_t GetAddressSpaceSize(std::size_t width, Type type);
23 23
24 const std::size_t bit_width{}; 24 const std::size_t bit_width{};
diff --git a/src/core/hle/kernel/k_client_port.cpp b/src/core/hle/kernel/k_client_port.cpp
index c72a91a76..700ae71e3 100644
--- a/src/core/hle/kernel/k_client_port.cpp
+++ b/src/core/hle/kernel/k_client_port.cpp
@@ -2,7 +2,6 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/scope_exit.h" 4#include "common/scope_exit.h"
5#include "core/hle/kernel/hle_ipc.h"
6#include "core/hle/kernel/k_client_port.h" 5#include "core/hle/kernel/k_client_port.h"
7#include "core/hle/kernel/k_port.h" 6#include "core/hle/kernel/k_port.h"
8#include "core/hle/kernel/k_scheduler.h" 7#include "core/hle/kernel/k_scheduler.h"
diff --git a/src/core/hle/kernel/k_client_port.h b/src/core/hle/kernel/k_client_port.h
index 81046fb86..a757cf9cd 100644
--- a/src/core/hle/kernel/k_client_port.h
+++ b/src/core/hle/kernel/k_client_port.h
@@ -15,7 +15,6 @@ namespace Kernel {
15class KClientSession; 15class KClientSession;
16class KernelCore; 16class KernelCore;
17class KPort; 17class KPort;
18class SessionRequestManager;
19 18
20class KClientPort final : public KSynchronizationObject { 19class KClientPort final : public KSynchronizationObject {
21 KERNEL_AUTOOBJECT_TRAITS(KClientPort, KSynchronizationObject); 20 KERNEL_AUTOOBJECT_TRAITS(KClientPort, KSynchronizationObject);
diff --git a/src/core/hle/kernel/k_client_session.cpp b/src/core/hle/kernel/k_client_session.cpp
index b4197a8d5..da0c9ac8c 100644
--- a/src/core/hle/kernel/k_client_session.cpp
+++ b/src/core/hle/kernel/k_client_session.cpp
@@ -2,7 +2,6 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/scope_exit.h" 4#include "common/scope_exit.h"
5#include "core/hle/kernel/hle_ipc.h"
6#include "core/hle/kernel/k_client_session.h" 5#include "core/hle/kernel/k_client_session.h"
7#include "core/hle/kernel/k_server_session.h" 6#include "core/hle/kernel/k_server_session.h"
8#include "core/hle/kernel/k_session.h" 7#include "core/hle/kernel/k_session.h"
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp
index 3f0be1c3f..f40cf92b1 100644
--- a/src/core/hle/kernel/k_condition_variable.cpp
+++ b/src/core/hle/kernel/k_condition_variable.cpp
@@ -111,36 +111,36 @@ Result KConditionVariable::SignalToAddress(VAddr addr) {
111 KScopedSchedulerLock sl(kernel); 111 KScopedSchedulerLock sl(kernel);
112 112
113 // Remove waiter thread. 113 // Remove waiter thread.
114 s32 num_waiters{}; 114 bool has_waiters{};
115 KThread* next_owner_thread = 115 KThread* const next_owner_thread =
116 owner_thread->RemoveWaiterByKey(std::addressof(num_waiters), addr); 116 owner_thread->RemoveUserWaiterByKey(std::addressof(has_waiters), addr);
117 117
118 // Determine the next tag. 118 // Determine the next tag.
119 u32 next_value{}; 119 u32 next_value{};
120 if (next_owner_thread != nullptr) { 120 if (next_owner_thread != nullptr) {
121 next_value = next_owner_thread->GetAddressKeyValue(); 121 next_value = next_owner_thread->GetAddressKeyValue();
122 if (num_waiters > 1) { 122 if (has_waiters) {
123 next_value |= Svc::HandleWaitMask; 123 next_value |= Svc::HandleWaitMask;
124 } 124 }
125 }
125 126
126 // Write the value to userspace. 127 // Synchronize memory before proceeding.
127 Result result{ResultSuccess}; 128 std::atomic_thread_fence(std::memory_order_seq_cst);
128 if (WriteToUser(system, addr, std::addressof(next_value))) [[likely]] {
129 result = ResultSuccess;
130 } else {
131 result = ResultInvalidCurrentMemory;
132 }
133 129
134 // Signal the next owner thread. 130 // Write the value to userspace.
135 next_owner_thread->EndWait(result); 131 Result result{ResultSuccess};
136 return result; 132 if (WriteToUser(system, addr, std::addressof(next_value))) [[likely]] {
133 result = ResultSuccess;
137 } else { 134 } else {
138 // Just write the value to userspace. 135 result = ResultInvalidCurrentMemory;
139 R_UNLESS(WriteToUser(system, addr, std::addressof(next_value)), 136 }
140 ResultInvalidCurrentMemory);
141 137
142 return ResultSuccess; 138 // If necessary, signal the next owner thread.
139 if (next_owner_thread != nullptr) {
140 next_owner_thread->EndWait(result);
143 } 141 }
142
143 R_RETURN(result);
144 } 144 }
145} 145}
146 146
@@ -198,7 +198,9 @@ void KConditionVariable::SignalImpl(KThread* thread) {
198 u32 prev_tag{}; 198 u32 prev_tag{};
199 bool can_access{}; 199 bool can_access{};
200 { 200 {
201 // TODO(bunnei): We should disable interrupts here via KScopedInterruptDisable. 201 // NOTE: If scheduler lock is not held here, interrupt disable is required.
202 // KScopedInterruptDisable di;
203
202 // TODO(bunnei): We should call CanAccessAtomic(..) here. 204 // TODO(bunnei): We should call CanAccessAtomic(..) here.
203 can_access = true; 205 can_access = true;
204 if (can_access) [[likely]] { 206 if (can_access) [[likely]] {
@@ -245,9 +247,11 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
245 (it->GetConditionVariableKey() == cv_key)) { 247 (it->GetConditionVariableKey() == cv_key)) {
246 KThread* target_thread = std::addressof(*it); 248 KThread* target_thread = std::addressof(*it);
247 249
248 this->SignalImpl(target_thread);
249 it = thread_tree.erase(it); 250 it = thread_tree.erase(it);
250 target_thread->ClearConditionVariable(); 251 target_thread->ClearConditionVariable();
252
253 this->SignalImpl(target_thread);
254
251 ++num_waiters; 255 ++num_waiters;
252 } 256 }
253 257
@@ -277,16 +281,16 @@ Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) {
277 // Update the value and process for the next owner. 281 // Update the value and process for the next owner.
278 { 282 {
279 // Remove waiter thread. 283 // Remove waiter thread.
280 s32 num_waiters{}; 284 bool has_waiters{};
281 KThread* next_owner_thread = 285 KThread* next_owner_thread =
282 cur_thread->RemoveWaiterByKey(std::addressof(num_waiters), addr); 286 cur_thread->RemoveUserWaiterByKey(std::addressof(has_waiters), addr);
283 287
284 // Update for the next owner thread. 288 // Update for the next owner thread.
285 u32 next_value{}; 289 u32 next_value{};
286 if (next_owner_thread != nullptr) { 290 if (next_owner_thread != nullptr) {
287 // Get the next tag value. 291 // Get the next tag value.
288 next_value = next_owner_thread->GetAddressKeyValue(); 292 next_value = next_owner_thread->GetAddressKeyValue();
289 if (num_waiters > 1) { 293 if (has_waiters) {
290 next_value |= Svc::HandleWaitMask; 294 next_value |= Svc::HandleWaitMask;
291 } 295 }
292 296
diff --git a/src/core/hle/kernel/k_device_address_space.h b/src/core/hle/kernel/k_device_address_space.h
index 4709df995..b4a014c38 100644
--- a/src/core/hle/kernel/k_device_address_space.h
+++ b/src/core/hle/kernel/k_device_address_space.h
@@ -21,9 +21,9 @@ public:
21 ~KDeviceAddressSpace(); 21 ~KDeviceAddressSpace();
22 22
23 Result Initialize(u64 address, u64 size); 23 Result Initialize(u64 address, u64 size);
24 void Finalize(); 24 void Finalize() override;
25 25
26 bool IsInitialized() const { 26 bool IsInitialized() const override {
27 return m_is_initialized; 27 return m_is_initialized;
28 } 28 }
29 static void PostDestroy(uintptr_t arg) {} 29 static void PostDestroy(uintptr_t arg) {}
diff --git a/src/core/hle/kernel/k_light_lock.cpp b/src/core/hle/kernel/k_light_lock.cpp
index d791acbe3..14cb615da 100644
--- a/src/core/hle/kernel/k_light_lock.cpp
+++ b/src/core/hle/kernel/k_light_lock.cpp
@@ -90,15 +90,15 @@ void KLightLock::UnlockSlowPath(uintptr_t _cur_thread) {
90 KScopedSchedulerLock sl(kernel); 90 KScopedSchedulerLock sl(kernel);
91 91
92 // Get the next owner. 92 // Get the next owner.
93 s32 num_waiters; 93 bool has_waiters;
94 KThread* next_owner = owner_thread->RemoveWaiterByKey( 94 KThread* next_owner = owner_thread->RemoveKernelWaiterByKey(
95 std::addressof(num_waiters), reinterpret_cast<uintptr_t>(std::addressof(tag))); 95 std::addressof(has_waiters), reinterpret_cast<uintptr_t>(std::addressof(tag)));
96 96
97 // Pass the lock to the next owner. 97 // Pass the lock to the next owner.
98 uintptr_t next_tag = 0; 98 uintptr_t next_tag = 0;
99 if (next_owner != nullptr) { 99 if (next_owner != nullptr) {
100 next_tag = 100 next_tag =
101 reinterpret_cast<uintptr_t>(next_owner) | static_cast<uintptr_t>(num_waiters > 1); 101 reinterpret_cast<uintptr_t>(next_owner) | static_cast<uintptr_t>(has_waiters);
102 102
103 next_owner->EndWait(ResultSuccess); 103 next_owner->EndWait(ResultSuccess);
104 104
diff --git a/src/core/hle/kernel/k_port.cpp b/src/core/hle/kernel/k_port.cpp
index 77d00ae2c..0a45ffd57 100644
--- a/src/core/hle/kernel/k_port.cpp
+++ b/src/core/hle/kernel/k_port.cpp
@@ -1,7 +1,6 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/hle_ipc.h"
5#include "core/hle/kernel/k_port.h" 4#include "core/hle/kernel/k_port.h"
6#include "core/hle/kernel/k_scheduler.h" 5#include "core/hle/kernel/k_scheduler.h"
7#include "core/hle/kernel/svc_results.h" 6#include "core/hle/kernel/svc_results.h"
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 0e4283a0c..d44f6e921 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -119,7 +119,6 @@ void KProcess::DecrementRunningThreadCount() {
119 119
120 if (const auto prev = num_running_threads--; prev == 1) { 120 if (const auto prev = num_running_threads--; prev == 1) {
121 // TODO(bunnei): Process termination to be implemented when multiprocess is supported. 121 // TODO(bunnei): Process termination to be implemented when multiprocess is supported.
122 UNIMPLEMENTED_MSG("KProcess termination is not implemennted!");
123 } 122 }
124} 123}
125 124
@@ -157,9 +156,9 @@ bool KProcess::ReleaseUserException(KThread* thread) {
157 exception_thread = nullptr; 156 exception_thread = nullptr;
158 157
159 // Remove waiter thread. 158 // Remove waiter thread.
160 s32 num_waiters{}; 159 bool has_waiters{};
161 if (KThread* next = thread->RemoveWaiterByKey( 160 if (KThread* next = thread->RemoveKernelWaiterByKey(
162 std::addressof(num_waiters), 161 std::addressof(has_waiters),
163 reinterpret_cast<uintptr_t>(std::addressof(exception_thread))); 162 reinterpret_cast<uintptr_t>(std::addressof(exception_thread)));
164 next != nullptr) { 163 next != nullptr) {
165 next->EndWait(ResultSuccess); 164 next->EndWait(ResultSuccess);
@@ -357,9 +356,6 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
357 system_resource_size = metadata.GetSystemResourceSize(); 356 system_resource_size = metadata.GetSystemResourceSize();
358 image_size = code_size; 357 image_size = code_size;
359 358
360 // We currently do not support process-specific system resource
361 UNIMPLEMENTED_IF(system_resource_size != 0);
362
363 KScopedResourceReservation memory_reservation( 359 KScopedResourceReservation memory_reservation(
364 resource_limit, LimitableResource::PhysicalMemoryMax, code_size + system_resource_size); 360 resource_limit, LimitableResource::PhysicalMemoryMax, code_size + system_resource_size);
365 if (!memory_reservation.Succeeded()) { 361 if (!memory_reservation.Succeeded()) {
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index 09bf2f1d0..549809000 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -310,10 +310,10 @@ public:
310 /// Clears the signaled state of the process if and only if it's signaled. 310 /// Clears the signaled state of the process if and only if it's signaled.
311 /// 311 ///
312 /// @pre The process must not be already terminated. If this is called on a 312 /// @pre The process must not be already terminated. If this is called on a
313 /// terminated process, then ERR_INVALID_STATE will be returned. 313 /// terminated process, then ResultInvalidState will be returned.
314 /// 314 ///
315 /// @pre The process must be in a signaled state. If this is called on a 315 /// @pre The process must be in a signaled state. If this is called on a
316 /// process instance that is not signaled, ERR_INVALID_STATE will be 316 /// process instance that is not signaled, ResultInvalidState will be
317 /// returned. 317 /// returned.
318 Result Reset(); 318 Result Reset();
319 319
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
index b9d22b414..626517619 100644
--- a/src/core/hle/kernel/k_resource_limit.cpp
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -2,6 +2,7 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/assert.h" 4#include "common/assert.h"
5#include "common/overflow.h"
5#include "core/core.h" 6#include "core/core.h"
6#include "core/core_timing.h" 7#include "core/core_timing.h"
7#include "core/hle/kernel/k_resource_limit.h" 8#include "core/hle/kernel/k_resource_limit.h"
@@ -104,7 +105,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
104 ASSERT(current_hints[index] <= current_values[index]); 105 ASSERT(current_hints[index] <= current_values[index]);
105 106
106 // If we would overflow, don't allow to succeed. 107 // If we would overflow, don't allow to succeed.
107 if (current_values[index] + value <= current_values[index]) { 108 if (Common::WrappingAdd(current_values[index], value) <= current_values[index]) {
108 break; 109 break;
109 } 110 }
110 111
diff --git a/src/core/hle/kernel/k_scheduler_lock.h b/src/core/hle/kernel/k_scheduler_lock.h
index 129d60472..13463717f 100644
--- a/src/core/hle/kernel/k_scheduler_lock.h
+++ b/src/core/hle/kernel/k_scheduler_lock.h
@@ -31,22 +31,23 @@ public:
31 } 31 }
32 32
33 if (IsLockedByCurrentThread()) { 33 if (IsLockedByCurrentThread()) {
34 // If we already own the lock, we can just increment the count. 34 // If we already own the lock, the lock count should be > 0.
35 // For debug, ensure this is true.
35 ASSERT(lock_count > 0); 36 ASSERT(lock_count > 0);
36 lock_count++;
37 } else { 37 } else {
38 // Otherwise, we want to disable scheduling and acquire the spinlock. 38 // Otherwise, we want to disable scheduling and acquire the spinlock.
39 SchedulerType::DisableScheduling(kernel); 39 SchedulerType::DisableScheduling(kernel);
40 spin_lock.Lock(); 40 spin_lock.Lock();
41 41
42 // For debug, ensure that our state is valid.
43 ASSERT(lock_count == 0); 42 ASSERT(lock_count == 0);
44 ASSERT(owner_thread == nullptr); 43 ASSERT(owner_thread == nullptr);
45 44
46 // Increment count, take ownership. 45 // Take ownership of the lock.
47 lock_count = 1;
48 owner_thread = GetCurrentThreadPointer(kernel); 46 owner_thread = GetCurrentThreadPointer(kernel);
49 } 47 }
48
49 // Increment the lock count.
50 lock_count++;
50 } 51 }
51 52
52 void Unlock() { 53 void Unlock() {
diff --git a/src/core/hle/kernel/k_scoped_lock.h b/src/core/hle/kernel/k_scoped_lock.h
index 59b3e32ae..a15640fd2 100644
--- a/src/core/hle/kernel/k_scoped_lock.h
+++ b/src/core/hle/kernel/k_scoped_lock.h
@@ -4,6 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include <concepts> 6#include <concepts>
7#include <memory>
7#include <type_traits> 8#include <type_traits>
8 9
9namespace Kernel { 10namespace Kernel {
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp
index aa1941f01..01591af5b 100644
--- a/src/core/hle/kernel/k_server_session.cpp
+++ b/src/core/hle/kernel/k_server_session.cpp
@@ -10,8 +10,6 @@
10#include "common/scope_exit.h" 10#include "common/scope_exit.h"
11#include "core/core.h" 11#include "core/core.h"
12#include "core/core_timing.h" 12#include "core/core_timing.h"
13#include "core/hle/ipc_helpers.h"
14#include "core/hle/kernel/hle_ipc.h"
15#include "core/hle/kernel/k_client_port.h" 13#include "core/hle/kernel/k_client_port.h"
16#include "core/hle/kernel/k_handle_table.h" 14#include "core/hle/kernel/k_handle_table.h"
17#include "core/hle/kernel/k_process.h" 15#include "core/hle/kernel/k_process.h"
@@ -22,6 +20,8 @@
22#include "core/hle/kernel/k_thread.h" 20#include "core/hle/kernel/k_thread.h"
23#include "core/hle/kernel/k_thread_queue.h" 21#include "core/hle/kernel/k_thread_queue.h"
24#include "core/hle/kernel/kernel.h" 22#include "core/hle/kernel/kernel.h"
23#include "core/hle/service/hle_ipc.h"
24#include "core/hle/service/ipc_helpers.h"
25#include "core/memory.h" 25#include "core/memory.h"
26 26
27namespace Kernel { 27namespace Kernel {
@@ -281,8 +281,8 @@ Result KServerSession::SendReply(bool is_hle) {
281 return result; 281 return result;
282} 282}
283 283
284Result KServerSession::ReceiveRequest(std::shared_ptr<HLERequestContext>* out_context, 284Result KServerSession::ReceiveRequest(std::shared_ptr<Service::HLERequestContext>* out_context,
285 std::weak_ptr<SessionRequestManager> manager) { 285 std::weak_ptr<Service::SessionRequestManager> manager) {
286 // Lock the session. 286 // Lock the session.
287 KScopedLightLock lk{m_lock}; 287 KScopedLightLock lk{m_lock};
288 288
@@ -329,7 +329,8 @@ Result KServerSession::ReceiveRequest(std::shared_ptr<HLERequestContext>* out_co
329 if (out_context != nullptr) { 329 if (out_context != nullptr) {
330 // HLE request. 330 // HLE request.
331 u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(client_message))}; 331 u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(client_message))};
332 *out_context = std::make_shared<HLERequestContext>(kernel, memory, this, client_thread); 332 *out_context =
333 std::make_shared<Service::HLERequestContext>(kernel, memory, this, client_thread);
333 (*out_context)->SetSessionRequestManager(manager); 334 (*out_context)->SetSessionRequestManager(manager);
334 (*out_context) 335 (*out_context)
335 ->PopulateFromIncomingCommandBuffer(client_thread->GetOwnerProcess()->GetHandleTable(), 336 ->PopulateFromIncomingCommandBuffer(client_thread->GetOwnerProcess()->GetHandleTable(),
diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h
index 6e189af8b..33f380352 100644
--- a/src/core/hle/kernel/k_server_session.h
+++ b/src/core/hle/kernel/k_server_session.h
@@ -10,18 +10,20 @@
10 10
11#include <boost/intrusive/list.hpp> 11#include <boost/intrusive/list.hpp>
12 12
13#include "core/hle/kernel/hle_ipc.h"
14#include "core/hle/kernel/k_light_lock.h" 13#include "core/hle/kernel/k_light_lock.h"
15#include "core/hle/kernel/k_session_request.h" 14#include "core/hle/kernel/k_session_request.h"
16#include "core/hle/kernel/k_synchronization_object.h" 15#include "core/hle/kernel/k_synchronization_object.h"
17#include "core/hle/result.h" 16#include "core/hle/result.h"
18 17
18namespace Service {
19class HLERequestContext;
20class SessionRequestManager;
21} // namespace Service
22
19namespace Kernel { 23namespace Kernel {
20 24
21class HLERequestContext;
22class KernelCore; 25class KernelCore;
23class KSession; 26class KSession;
24class SessionRequestManager;
25class KThread; 27class KThread;
26 28
27class KServerSession final : public KSynchronizationObject, 29class KServerSession final : public KSynchronizationObject,
@@ -52,8 +54,8 @@ public:
52 /// TODO: flesh these out to match the real kernel 54 /// TODO: flesh these out to match the real kernel
53 Result OnRequest(KSessionRequest* request); 55 Result OnRequest(KSessionRequest* request);
54 Result SendReply(bool is_hle = false); 56 Result SendReply(bool is_hle = false);
55 Result ReceiveRequest(std::shared_ptr<HLERequestContext>* out_context = nullptr, 57 Result ReceiveRequest(std::shared_ptr<Service::HLERequestContext>* out_context = nullptr,
56 std::weak_ptr<SessionRequestManager> manager = {}); 58 std::weak_ptr<Service::SessionRequestManager> manager = {});
57 59
58 Result SendReplyHLE() { 60 Result SendReplyHLE() {
59 return SendReply(true); 61 return SendReply(true);
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 2d3da9d66..8c403f5fd 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -29,6 +29,7 @@
29#include "core/hle/kernel/k_thread_queue.h" 29#include "core/hle/kernel/k_thread_queue.h"
30#include "core/hle/kernel/k_worker_task_manager.h" 30#include "core/hle/kernel/k_worker_task_manager.h"
31#include "core/hle/kernel/kernel.h" 31#include "core/hle/kernel/kernel.h"
32#include "core/hle/kernel/svc.h"
32#include "core/hle/kernel/svc_results.h" 33#include "core/hle/kernel/svc_results.h"
33#include "core/hle/kernel/svc_types.h" 34#include "core/hle/kernel/svc_types.h"
34#include "core/hle/result.h" 35#include "core/hle/result.h"
@@ -190,7 +191,7 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack
190 light_ipc_data = nullptr; 191 light_ipc_data = nullptr;
191 192
192 // We're not waiting for a lock, and we haven't disabled migration. 193 // We're not waiting for a lock, and we haven't disabled migration.
193 lock_owner = nullptr; 194 waiting_lock_info = nullptr;
194 num_core_migration_disables = 0; 195 num_core_migration_disables = 0;
195 196
196 // We have no waiters, but we do have an entrypoint. 197 // We have no waiters, but we do have an entrypoint.
@@ -298,6 +299,25 @@ Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThr
298 ThreadType::User, system.GetCpuManager().GetGuestThreadFunc())); 299 ThreadType::User, system.GetCpuManager().GetGuestThreadFunc()));
299} 300}
300 301
302Result KThread::InitializeServiceThread(Core::System& system, KThread* thread,
303 std::function<void()>&& func, s32 prio, s32 virt_core,
304 KProcess* owner) {
305 system.Kernel().GlobalSchedulerContext().AddThread(thread);
306 std::function<void()> func2{[&system, func{std::move(func)}] {
307 // Similar to UserModeThreadStarter.
308 system.Kernel().CurrentScheduler()->OnThreadStart();
309
310 // Run the guest function.
311 func();
312
313 // Exit.
314 Svc::ExitThread(system);
315 }};
316
317 R_RETURN(InitializeThread(thread, {}, {}, {}, prio, virt_core, owner, ThreadType::HighPriority,
318 std::move(func2)));
319}
320
301void KThread::PostDestroy(uintptr_t arg) { 321void KThread::PostDestroy(uintptr_t arg) {
302 KProcess* owner = reinterpret_cast<KProcess*>(arg & ~1ULL); 322 KProcess* owner = reinterpret_cast<KProcess*>(arg & ~1ULL);
303 const bool resource_limit_release_hint = (arg & 1); 323 const bool resource_limit_release_hint = (arg & 1);
@@ -321,25 +341,39 @@ void KThread::Finalize() {
321 341
322 // Release any waiters. 342 // Release any waiters.
323 { 343 {
324 ASSERT(lock_owner == nullptr); 344 ASSERT(waiting_lock_info == nullptr);
325 KScopedSchedulerLock sl{kernel}; 345 KScopedSchedulerLock sl{kernel};
326 346
327 auto it = waiter_list.begin(); 347 // Check that we have no kernel waiters.
328 while (it != waiter_list.end()) { 348 ASSERT(num_kernel_waiters == 0);
329 // Get the thread. 349
330 KThread* const waiter = std::addressof(*it); 350 auto it = held_lock_info_list.begin();
351 while (it != held_lock_info_list.end()) {
352 // Get the lock info.
353 auto* const lock_info = std::addressof(*it);
354
355 // The lock shouldn't have a kernel waiter.
356 ASSERT(!lock_info->GetIsKernelAddressKey());
331 357
332 // The thread shouldn't be a kernel waiter. 358 // Remove all waiters.
333 ASSERT(!waiter->GetAddressKeyIsKernel()); 359 while (lock_info->GetWaiterCount() != 0) {
360 // Get the front waiter.
361 KThread* const waiter = lock_info->GetHighestPriorityWaiter();
362
363 // Remove it from the lock.
364 if (lock_info->RemoveWaiter(waiter)) {
365 ASSERT(lock_info->GetWaiterCount() == 0);
366 }
334 367
335 // Clear the lock owner. 368 // Cancel the thread's wait.
336 waiter->SetLockOwner(nullptr); 369 waiter->CancelWait(ResultInvalidState, true);
370 }
337 371
338 // Erase the waiter from our list. 372 // Remove the held lock from our list.
339 it = waiter_list.erase(it); 373 it = held_lock_info_list.erase(it);
340 374
341 // Cancel the thread's wait. 375 // Free the lock info.
342 waiter->CancelWait(ResultInvalidState, true); 376 LockWithPriorityInheritanceInfo::Free(kernel, lock_info);
343 } 377 }
344 } 378 }
345 379
@@ -688,6 +722,24 @@ void KThread::SetBasePriority(s32 value) {
688 RestorePriority(kernel, this); 722 RestorePriority(kernel, this);
689} 723}
690 724
725KThread* KThread::GetLockOwner() const {
726 return waiting_lock_info != nullptr ? waiting_lock_info->GetOwner() : nullptr;
727}
728
729void KThread::IncreaseBasePriority(s32 priority_) {
730 ASSERT(Svc::HighestThreadPriority <= priority_ && priority_ <= Svc::LowestThreadPriority);
731 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
732 ASSERT(!this->GetStackParameters().is_pinned);
733
734 // Set our base priority.
735 if (base_priority > priority_) {
736 base_priority = priority_;
737
738 // Perform a priority restoration.
739 RestorePriority(kernel, this);
740 }
741}
742
691void KThread::RequestSuspend(SuspendType type) { 743void KThread::RequestSuspend(SuspendType type) {
692 KScopedSchedulerLock sl{kernel}; 744 KScopedSchedulerLock sl{kernel};
693 745
@@ -871,51 +923,89 @@ Result KThread::GetThreadContext3(std::vector<u8>& out) {
871 R_SUCCEED(); 923 R_SUCCEED();
872} 924}
873 925
874void KThread::AddWaiterImpl(KThread* thread) { 926void KThread::AddHeldLock(LockWithPriorityInheritanceInfo* lock_info) {
875 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 927 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
928
929 // Set ourselves as the lock's owner.
930 lock_info->SetOwner(this);
931
932 // Add the lock to our held list.
933 held_lock_info_list.push_front(*lock_info);
934}
935
936KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(VAddr address_key_,
937 bool is_kernel_address_key_) {
938 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
876 939
877 // Find the right spot to insert the waiter. 940 // Try to find an existing held lock.
878 auto it = waiter_list.begin(); 941 for (auto& held_lock : held_lock_info_list) {
879 while (it != waiter_list.end()) { 942 if (held_lock.GetAddressKey() == address_key_ &&
880 if (it->GetPriority() > thread->GetPriority()) { 943 held_lock.GetIsKernelAddressKey() == is_kernel_address_key_) {
881 break; 944 return std::addressof(held_lock);
882 } 945 }
883 it++;
884 } 946 }
885 947
948 return nullptr;
949}
950
951void KThread::AddWaiterImpl(KThread* thread) {
952 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
953 ASSERT(thread->GetConditionVariableTree() == nullptr);
954
955 // Get the thread's address key.
956 const auto address_key_ = thread->GetAddressKey();
957 const auto is_kernel_address_key_ = thread->GetIsKernelAddressKey();
958
886 // Keep track of how many kernel waiters we have. 959 // Keep track of how many kernel waiters we have.
887 if (thread->GetAddressKeyIsKernel()) { 960 if (is_kernel_address_key_) {
888 ASSERT((num_kernel_waiters++) >= 0); 961 ASSERT((num_kernel_waiters++) >= 0);
889 KScheduler::SetSchedulerUpdateNeeded(kernel); 962 KScheduler::SetSchedulerUpdateNeeded(kernel);
890 } 963 }
891 964
892 // Insert the waiter. 965 // Get the relevant lock info.
893 waiter_list.insert(it, *thread); 966 auto* lock_info = this->FindHeldLock(address_key_, is_kernel_address_key_);
894 thread->SetLockOwner(this); 967 if (lock_info == nullptr) {
968 // Create a new lock for the address key.
969 lock_info =
970 LockWithPriorityInheritanceInfo::Create(kernel, address_key_, is_kernel_address_key_);
971
972 // Add the new lock to our list.
973 this->AddHeldLock(lock_info);
974 }
975
976 // Add the thread as waiter to the lock info.
977 lock_info->AddWaiter(thread);
895} 978}
896 979
897void KThread::RemoveWaiterImpl(KThread* thread) { 980void KThread::RemoveWaiterImpl(KThread* thread) {
898 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 981 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
899 982
900 // Keep track of how many kernel waiters we have. 983 // Keep track of how many kernel waiters we have.
901 if (thread->GetAddressKeyIsKernel()) { 984 if (thread->GetIsKernelAddressKey()) {
902 ASSERT((num_kernel_waiters--) > 0); 985 ASSERT((num_kernel_waiters--) > 0);
903 KScheduler::SetSchedulerUpdateNeeded(kernel); 986 KScheduler::SetSchedulerUpdateNeeded(kernel);
904 } 987 }
905 988
989 // Get the info for the lock the thread is waiting on.
990 auto* lock_info = thread->GetWaitingLockInfo();
991 ASSERT(lock_info->GetOwner() == this);
992
906 // Remove the waiter. 993 // Remove the waiter.
907 waiter_list.erase(waiter_list.iterator_to(*thread)); 994 if (lock_info->RemoveWaiter(thread)) {
908 thread->SetLockOwner(nullptr); 995 held_lock_info_list.erase(held_lock_info_list.iterator_to(*lock_info));
996 LockWithPriorityInheritanceInfo::Free(kernel, lock_info);
997 }
909} 998}
910 999
911void KThread::RestorePriority(KernelCore& kernel_ctx, KThread* thread) { 1000void KThread::RestorePriority(KernelCore& kernel, KThread* thread) {
912 ASSERT(kernel_ctx.GlobalSchedulerContext().IsLocked()); 1001 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
913 1002
914 while (true) { 1003 while (thread != nullptr) {
915 // We want to inherit priority where possible. 1004 // We want to inherit priority where possible.
916 s32 new_priority = thread->GetBasePriority(); 1005 s32 new_priority = thread->GetBasePriority();
917 if (thread->HasWaiters()) { 1006 for (const auto& held_lock : thread->held_lock_info_list) {
918 new_priority = std::min(new_priority, thread->waiter_list.front().GetPriority()); 1007 new_priority =
1008 std::min(new_priority, held_lock.GetHighestPriorityWaiter()->GetPriority());
919 } 1009 }
920 1010
921 // If the priority we would inherit is not different from ours, don't do anything. 1011 // If the priority we would inherit is not different from ours, don't do anything.
@@ -923,9 +1013,18 @@ void KThread::RestorePriority(KernelCore& kernel_ctx, KThread* thread) {
923 return; 1013 return;
924 } 1014 }
925 1015
1016 // Get the owner of whatever lock this thread is waiting on.
1017 KThread* const lock_owner = thread->GetLockOwner();
1018
1019 // If the thread is waiting on some lock, remove it as a waiter to prevent violating red
1020 // black tree invariants.
1021 if (lock_owner != nullptr) {
1022 lock_owner->RemoveWaiterImpl(thread);
1023 }
1024
926 // Ensure we don't violate condition variable red black tree invariants. 1025 // Ensure we don't violate condition variable red black tree invariants.
927 if (auto* cv_tree = thread->GetConditionVariableTree(); cv_tree != nullptr) { 1026 if (auto* cv_tree = thread->GetConditionVariableTree(); cv_tree != nullptr) {
928 BeforeUpdatePriority(kernel_ctx, cv_tree, thread); 1027 BeforeUpdatePriority(kernel, cv_tree, thread);
929 } 1028 }
930 1029
931 // Change the priority. 1030 // Change the priority.
@@ -934,73 +1033,99 @@ void KThread::RestorePriority(KernelCore& kernel_ctx, KThread* thread) {
934 1033
935 // Restore the condition variable, if relevant. 1034 // Restore the condition variable, if relevant.
936 if (auto* cv_tree = thread->GetConditionVariableTree(); cv_tree != nullptr) { 1035 if (auto* cv_tree = thread->GetConditionVariableTree(); cv_tree != nullptr) {
937 AfterUpdatePriority(kernel_ctx, cv_tree, thread); 1036 AfterUpdatePriority(kernel, cv_tree, thread);
938 } 1037 }
939 1038
940 // Update the scheduler. 1039 // If we removed the thread from some lock's waiting list, add it back.
941 KScheduler::OnThreadPriorityChanged(kernel_ctx, thread, old_priority); 1040 if (lock_owner != nullptr) {
942 1041 lock_owner->AddWaiterImpl(thread);
943 // Keep the lock owner up to date.
944 KThread* lock_owner = thread->GetLockOwner();
945 if (lock_owner == nullptr) {
946 return;
947 } 1042 }
948 1043
949 // Update the thread in the lock owner's sorted list, and continue inheriting. 1044 // Update the scheduler.
950 lock_owner->RemoveWaiterImpl(thread); 1045 KScheduler::OnThreadPriorityChanged(kernel, thread, old_priority);
951 lock_owner->AddWaiterImpl(thread); 1046
1047 // Continue inheriting priority.
952 thread = lock_owner; 1048 thread = lock_owner;
953 } 1049 }
954} 1050}
955 1051
956void KThread::AddWaiter(KThread* thread) { 1052void KThread::AddWaiter(KThread* thread) {
957 AddWaiterImpl(thread); 1053 this->AddWaiterImpl(thread);
958 RestorePriority(kernel, this); 1054
1055 // If the thread has a higher priority than us, we should inherit.
1056 if (thread->GetPriority() < this->GetPriority()) {
1057 RestorePriority(kernel, this);
1058 }
959} 1059}
960 1060
961void KThread::RemoveWaiter(KThread* thread) { 1061void KThread::RemoveWaiter(KThread* thread) {
962 RemoveWaiterImpl(thread); 1062 this->RemoveWaiterImpl(thread);
963 RestorePriority(kernel, this); 1063
1064 // If our priority is the same as the thread's (and we've inherited), we may need to restore to
1065 // lower priority.
1066 if (this->GetPriority() == thread->GetPriority() &&
1067 this->GetPriority() < this->GetBasePriority()) {
1068 RestorePriority(kernel, this);
1069 }
964} 1070}
965 1071
966KThread* KThread::RemoveWaiterByKey(s32* out_num_waiters, VAddr key) { 1072KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, VAddr key, bool is_kernel_address_key_) {
967 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 1073 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
968 1074
969 s32 num_waiters{}; 1075 // Get the relevant lock info.
970 KThread* next_lock_owner{}; 1076 auto* lock_info = this->FindHeldLock(key, is_kernel_address_key_);
971 auto it = waiter_list.begin(); 1077 if (lock_info == nullptr) {
972 while (it != waiter_list.end()) { 1078 *out_has_waiters = false;
973 if (it->GetAddressKey() == key) { 1079 return nullptr;
974 KThread* thread = std::addressof(*it); 1080 }
975
976 // Keep track of how many kernel waiters we have.
977 if (thread->GetAddressKeyIsKernel()) {
978 ASSERT((num_kernel_waiters--) > 0);
979 KScheduler::SetSchedulerUpdateNeeded(kernel);
980 }
981 it = waiter_list.erase(it);
982 1081
983 // Update the next lock owner. 1082 // Remove the lock info from our held list.
984 if (next_lock_owner == nullptr) { 1083 held_lock_info_list.erase(held_lock_info_list.iterator_to(*lock_info));
985 next_lock_owner = thread; 1084
986 next_lock_owner->SetLockOwner(nullptr); 1085 // Keep track of how many kernel waiters we have.
987 } else { 1086 if (lock_info->GetIsKernelAddressKey()) {
988 next_lock_owner->AddWaiterImpl(thread); 1087 num_kernel_waiters -= lock_info->GetWaiterCount();
989 } 1088 ASSERT(num_kernel_waiters >= 0);
990 num_waiters++; 1089 KScheduler::SetSchedulerUpdateNeeded(kernel);
991 } else { 1090 }
992 it++; 1091
1092 ASSERT(lock_info->GetWaiterCount() > 0);
1093
1094 // Remove the highest priority waiter from the lock to be the next owner.
1095 KThread* next_lock_owner = lock_info->GetHighestPriorityWaiter();
1096 if (lock_info->RemoveWaiter(next_lock_owner)) {
1097 // The new owner was the only waiter.
1098 *out_has_waiters = false;
1099
1100 // Free the lock info, since it has no waiters.
1101 LockWithPriorityInheritanceInfo::Free(kernel, lock_info);
1102 } else {
1103 // There are additional waiters on the lock.
1104 *out_has_waiters = true;
1105
1106 // Add the lock to the new owner's held list.
1107 next_lock_owner->AddHeldLock(lock_info);
1108
1109 // Keep track of any kernel waiters for the new owner.
1110 if (lock_info->GetIsKernelAddressKey()) {
1111 next_lock_owner->num_kernel_waiters += lock_info->GetWaiterCount();
1112 ASSERT(next_lock_owner->num_kernel_waiters > 0);
1113
1114 // NOTE: No need to set scheduler update needed, because we will have already done so
1115 // when removing earlier.
993 } 1116 }
994 } 1117 }
995 1118
996 // Do priority updates, if we have a next owner. 1119 // If our priority is the same as the next owner's (and we've inherited), we may need to restore
997 if (next_lock_owner) { 1120 // to lower priority.
1121 if (this->GetPriority() == next_lock_owner->GetPriority() &&
1122 this->GetPriority() < this->GetBasePriority()) {
998 RestorePriority(kernel, this); 1123 RestorePriority(kernel, this);
999 RestorePriority(kernel, next_lock_owner); 1124 // NOTE: No need to restore priority on the next lock owner, because it was already the
1125 // highest priority waiter on the lock.
1000 } 1126 }
1001 1127
1002 // Return output. 1128 // Return the next lock owner.
1003 *out_num_waiters = num_waiters;
1004 return next_lock_owner; 1129 return next_lock_owner;
1005} 1130}
1006 1131
@@ -1117,9 +1242,7 @@ ThreadState KThread::RequestTerminate() {
1117 } 1242 }
1118 1243
1119 // Change the thread's priority to be higher than any system thread's. 1244 // Change the thread's priority to be higher than any system thread's.
1120 if (this->GetBasePriority() >= Svc::SystemThreadPriorityHighest) { 1245 this->IncreaseBasePriority(TerminatingThreadPriority);
1121 this->SetBasePriority(TerminatingThreadPriority);
1122 }
1123 1246
1124 // If the thread is runnable, send a termination interrupt to other cores. 1247 // If the thread is runnable, send a termination interrupt to other cores.
1125 if (this->GetState() == ThreadState::Runnable) { 1248 if (this->GetState() == ThreadState::Runnable) {
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index ca82ce3b6..bd125f5f1 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -339,13 +339,7 @@ public:
339 void SetInterruptFlag(); 339 void SetInterruptFlag();
340 void ClearInterruptFlag(); 340 void ClearInterruptFlag();
341 341
342 [[nodiscard]] KThread* GetLockOwner() const { 342 KThread* GetLockOwner() const;
343 return lock_owner;
344 }
345
346 void SetLockOwner(KThread* owner) {
347 lock_owner = owner;
348 }
349 343
350 [[nodiscard]] const KAffinityMask& GetAffinityMask() const { 344 [[nodiscard]] const KAffinityMask& GetAffinityMask() const {
351 return physical_affinity_mask; 345 return physical_affinity_mask;
@@ -434,6 +428,10 @@ public:
434 VAddr user_stack_top, s32 prio, s32 virt_core, 428 VAddr user_stack_top, s32 prio, s32 virt_core,
435 KProcess* owner); 429 KProcess* owner);
436 430
431 [[nodiscard]] static Result InitializeServiceThread(Core::System& system, KThread* thread,
432 std::function<void()>&& thread_func,
433 s32 prio, s32 virt_core, KProcess* owner);
434
437public: 435public:
438 struct StackParameters { 436 struct StackParameters {
439 u8 svc_permission[0x10]; 437 u8 svc_permission[0x10];
@@ -597,7 +595,13 @@ public:
597 595
598 [[nodiscard]] Result GetThreadContext3(std::vector<u8>& out); 596 [[nodiscard]] Result GetThreadContext3(std::vector<u8>& out);
599 597
600 [[nodiscard]] KThread* RemoveWaiterByKey(s32* out_num_waiters, VAddr key); 598 [[nodiscard]] KThread* RemoveUserWaiterByKey(bool* out_has_waiters, VAddr key) {
599 return this->RemoveWaiterByKey(out_has_waiters, key, false);
600 }
601
602 [[nodiscard]] KThread* RemoveKernelWaiterByKey(bool* out_has_waiters, VAddr key) {
603 return this->RemoveWaiterByKey(out_has_waiters, key, true);
604 }
601 605
602 [[nodiscard]] VAddr GetAddressKey() const { 606 [[nodiscard]] VAddr GetAddressKey() const {
603 return address_key; 607 return address_key;
@@ -607,8 +611,8 @@ public:
607 return address_key_value; 611 return address_key_value;
608 } 612 }
609 613
610 [[nodiscard]] bool GetAddressKeyIsKernel() const { 614 [[nodiscard]] bool GetIsKernelAddressKey() const {
611 return address_key_is_kernel; 615 return is_kernel_address_key;
612 } 616 }
613 617
614 //! NB: intentional deviation from official kernel. 618 //! NB: intentional deviation from official kernel.
@@ -617,20 +621,17 @@ public:
617 // to cope with arbitrary host pointers making their way 621 // to cope with arbitrary host pointers making their way
618 // into things. 622 // into things.
619 623
620 void SetUserAddressKey(VAddr key) {
621 address_key = key;
622 address_key_is_kernel = false;
623 }
624
625 void SetUserAddressKey(VAddr key, u32 val) { 624 void SetUserAddressKey(VAddr key, u32 val) {
625 ASSERT(waiting_lock_info == nullptr);
626 address_key = key; 626 address_key = key;
627 address_key_value = val; 627 address_key_value = val;
628 address_key_is_kernel = false; 628 is_kernel_address_key = false;
629 } 629 }
630 630
631 void SetKernelAddressKey(VAddr key) { 631 void SetKernelAddressKey(VAddr key) {
632 ASSERT(waiting_lock_info == nullptr);
632 address_key = key; 633 address_key = key;
633 address_key_is_kernel = true; 634 is_kernel_address_key = true;
634 } 635 }
635 636
636 void ClearWaitQueue() { 637 void ClearWaitQueue() {
@@ -642,10 +643,6 @@ public:
642 void EndWait(Result wait_result_); 643 void EndWait(Result wait_result_);
643 void CancelWait(Result wait_result_, bool cancel_timer_task); 644 void CancelWait(Result wait_result_, bool cancel_timer_task);
644 645
645 [[nodiscard]] bool HasWaiters() const {
646 return !waiter_list.empty();
647 }
648
649 [[nodiscard]] s32 GetNumKernelWaiters() const { 646 [[nodiscard]] s32 GetNumKernelWaiters() const {
650 return num_kernel_waiters; 647 return num_kernel_waiters;
651 } 648 }
@@ -675,6 +672,9 @@ public:
675 } 672 }
676 673
677private: 674private:
675 [[nodiscard]] KThread* RemoveWaiterByKey(bool* out_has_waiters, VAddr key,
676 bool is_kernel_address_key);
677
678 static constexpr size_t PriorityInheritanceCountMax = 10; 678 static constexpr size_t PriorityInheritanceCountMax = 10;
679 union SyncObjectBuffer { 679 union SyncObjectBuffer {
680 std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{}; 680 std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{};
@@ -718,13 +718,14 @@ private:
718 }; 718 };
719 719
720 void AddWaiterImpl(KThread* thread); 720 void AddWaiterImpl(KThread* thread);
721
722 void RemoveWaiterImpl(KThread* thread); 721 void RemoveWaiterImpl(KThread* thread);
722 static void RestorePriority(KernelCore& kernel, KThread* thread);
723 723
724 void StartTermination(); 724 void StartTermination();
725
726 void FinishTermination(); 725 void FinishTermination();
727 726
727 void IncreaseBasePriority(s32 priority);
728
728 [[nodiscard]] Result Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, 729 [[nodiscard]] Result Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top,
729 s32 prio, s32 virt_core, KProcess* owner, ThreadType type); 730 s32 prio, s32 virt_core, KProcess* owner, ThreadType type);
730 731
@@ -733,8 +734,6 @@ private:
733 s32 core, KProcess* owner, ThreadType type, 734 s32 core, KProcess* owner, ThreadType type,
734 std::function<void()>&& init_func); 735 std::function<void()>&& init_func);
735 736
736 static void RestorePriority(KernelCore& kernel_ctx, KThread* thread);
737
738 // For core KThread implementation 737 // For core KThread implementation
739 ThreadContext32 thread_context_32{}; 738 ThreadContext32 thread_context_32{};
740 ThreadContext64 thread_context_64{}; 739 ThreadContext64 thread_context_64{};
@@ -745,6 +744,127 @@ private:
745 &KThread::condvar_arbiter_tree_node>; 744 &KThread::condvar_arbiter_tree_node>;
746 using ConditionVariableThreadTree = 745 using ConditionVariableThreadTree =
747 ConditionVariableThreadTreeTraits::TreeType<ConditionVariableComparator>; 746 ConditionVariableThreadTreeTraits::TreeType<ConditionVariableComparator>;
747
748private:
749 struct LockWithPriorityInheritanceComparator {
750 struct RedBlackKeyType {
751 s32 m_priority;
752
753 constexpr s32 GetPriority() const {
754 return m_priority;
755 }
756 };
757
758 template <typename T>
759 requires(std::same_as<T, KThread> || std::same_as<T, RedBlackKeyType>)
760 static constexpr int Compare(const T& lhs, const KThread& rhs) {
761 if (lhs.GetPriority() < rhs.GetPriority()) {
762 // Sort by priority.
763 return -1;
764 } else {
765 return 1;
766 }
767 }
768 };
769 static_assert(std::same_as<Common::RedBlackKeyType<LockWithPriorityInheritanceComparator, void>,
770 LockWithPriorityInheritanceComparator::RedBlackKeyType>);
771
772 using LockWithPriorityInheritanceThreadTreeTraits =
773 Common::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<
774 &KThread::condvar_arbiter_tree_node>;
775 using LockWithPriorityInheritanceThreadTree =
776 ConditionVariableThreadTreeTraits::TreeType<LockWithPriorityInheritanceComparator>;
777
778public:
779 class LockWithPriorityInheritanceInfo : public KSlabAllocated<LockWithPriorityInheritanceInfo>,
780 public boost::intrusive::list_base_hook<> {
781 public:
782 explicit LockWithPriorityInheritanceInfo(KernelCore&) {}
783
784 static LockWithPriorityInheritanceInfo* Create(KernelCore& kernel, VAddr address_key,
785 bool is_kernel_address_key) {
786 // Create a new lock info.
787 auto* new_lock = LockWithPriorityInheritanceInfo::Allocate(kernel);
788 ASSERT(new_lock != nullptr);
789
790 // Set the new lock's address key.
791 new_lock->m_address_key = address_key;
792 new_lock->m_is_kernel_address_key = is_kernel_address_key;
793
794 return new_lock;
795 }
796
797 void SetOwner(KThread* new_owner) {
798 // Set new owner.
799 m_owner = new_owner;
800 }
801
802 void AddWaiter(KThread* waiter) {
803 // Insert the waiter.
804 m_tree.insert(*waiter);
805 m_waiter_count++;
806
807 waiter->SetWaitingLockInfo(this);
808 }
809
810 [[nodiscard]] bool RemoveWaiter(KThread* waiter) {
811 m_tree.erase(m_tree.iterator_to(*waiter));
812
813 waiter->SetWaitingLockInfo(nullptr);
814
815 return (--m_waiter_count) == 0;
816 }
817
818 KThread* GetHighestPriorityWaiter() {
819 return std::addressof(m_tree.front());
820 }
821 const KThread* GetHighestPriorityWaiter() const {
822 return std::addressof(m_tree.front());
823 }
824
825 LockWithPriorityInheritanceThreadTree& GetThreadTree() {
826 return m_tree;
827 }
828 const LockWithPriorityInheritanceThreadTree& GetThreadTree() const {
829 return m_tree;
830 }
831
832 VAddr GetAddressKey() const {
833 return m_address_key;
834 }
835 bool GetIsKernelAddressKey() const {
836 return m_is_kernel_address_key;
837 }
838 KThread* GetOwner() const {
839 return m_owner;
840 }
841 u32 GetWaiterCount() const {
842 return m_waiter_count;
843 }
844
845 private:
846 LockWithPriorityInheritanceThreadTree m_tree{};
847 VAddr m_address_key{};
848 KThread* m_owner{};
849 u32 m_waiter_count{};
850 bool m_is_kernel_address_key{};
851 };
852
853 void SetWaitingLockInfo(LockWithPriorityInheritanceInfo* lock) {
854 waiting_lock_info = lock;
855 }
856
857 LockWithPriorityInheritanceInfo* GetWaitingLockInfo() {
858 return waiting_lock_info;
859 }
860
861 void AddHeldLock(LockWithPriorityInheritanceInfo* lock_info);
862 LockWithPriorityInheritanceInfo* FindHeldLock(VAddr address_key, bool is_kernel_address_key);
863
864private:
865 using LockWithPriorityInheritanceInfoList =
866 boost::intrusive::list<LockWithPriorityInheritanceInfo>;
867
748 ConditionVariableThreadTree* condvar_tree{}; 868 ConditionVariableThreadTree* condvar_tree{};
749 u64 condvar_key{}; 869 u64 condvar_key{};
750 u64 virtual_affinity_mask{}; 870 u64 virtual_affinity_mask{};
@@ -761,9 +881,9 @@ private:
761 s64 last_scheduled_tick{}; 881 s64 last_scheduled_tick{};
762 std::array<QueueEntry, Core::Hardware::NUM_CPU_CORES> per_core_priority_queue_entry{}; 882 std::array<QueueEntry, Core::Hardware::NUM_CPU_CORES> per_core_priority_queue_entry{};
763 KThreadQueue* wait_queue{}; 883 KThreadQueue* wait_queue{};
764 WaiterList waiter_list{}; 884 LockWithPriorityInheritanceInfoList held_lock_info_list{};
885 LockWithPriorityInheritanceInfo* waiting_lock_info{};
765 WaiterList pinned_waiter_list{}; 886 WaiterList pinned_waiter_list{};
766 KThread* lock_owner{};
767 u32 address_key_value{}; 887 u32 address_key_value{};
768 u32 suspend_request_flags{}; 888 u32 suspend_request_flags{};
769 u32 suspend_allowed_flags{}; 889 u32 suspend_allowed_flags{};
@@ -787,7 +907,7 @@ private:
787 bool debug_attached{}; 907 bool debug_attached{};
788 s8 priority_inheritance_count{}; 908 s8 priority_inheritance_count{};
789 bool resource_limit_release_hint{}; 909 bool resource_limit_release_hint{};
790 bool address_key_is_kernel{}; 910 bool is_kernel_address_key{};
791 StackParameters stack_parameters{}; 911 StackParameters stack_parameters{};
792 Common::SpinLock context_guard{}; 912 Common::SpinLock context_guard{};
793 913
@@ -810,10 +930,12 @@ public:
810 930
811 void SetConditionVariable(ConditionVariableThreadTree* tree, VAddr address, u64 cv_key, 931 void SetConditionVariable(ConditionVariableThreadTree* tree, VAddr address, u64 cv_key,
812 u32 value) { 932 u32 value) {
933 ASSERT(waiting_lock_info == nullptr);
813 condvar_tree = tree; 934 condvar_tree = tree;
814 condvar_key = cv_key; 935 condvar_key = cv_key;
815 address_key = address; 936 address_key = address;
816 address_key_value = value; 937 address_key_value = value;
938 is_kernel_address_key = false;
817 } 939 }
818 940
819 void ClearConditionVariable() { 941 void ClearConditionVariable() {
@@ -825,6 +947,7 @@ public:
825 } 947 }
826 948
827 void SetAddressArbiter(ConditionVariableThreadTree* tree, u64 address) { 949 void SetAddressArbiter(ConditionVariableThreadTree* tree, u64 address) {
950 ASSERT(waiting_lock_info == nullptr);
828 condvar_tree = tree; 951 condvar_tree = tree;
829 condvar_key = address; 952 condvar_key = address;
830 } 953 }
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 2ff253183..ef7057ff7 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -34,14 +34,15 @@
34#include "core/hle/kernel/k_process.h" 34#include "core/hle/kernel/k_process.h"
35#include "core/hle/kernel/k_resource_limit.h" 35#include "core/hle/kernel/k_resource_limit.h"
36#include "core/hle/kernel/k_scheduler.h" 36#include "core/hle/kernel/k_scheduler.h"
37#include "core/hle/kernel/k_scoped_resource_reservation.h"
37#include "core/hle/kernel/k_shared_memory.h" 38#include "core/hle/kernel/k_shared_memory.h"
38#include "core/hle/kernel/k_system_resource.h" 39#include "core/hle/kernel/k_system_resource.h"
39#include "core/hle/kernel/k_thread.h" 40#include "core/hle/kernel/k_thread.h"
40#include "core/hle/kernel/k_worker_task_manager.h" 41#include "core/hle/kernel/k_worker_task_manager.h"
41#include "core/hle/kernel/kernel.h" 42#include "core/hle/kernel/kernel.h"
42#include "core/hle/kernel/physical_core.h" 43#include "core/hle/kernel/physical_core.h"
43#include "core/hle/kernel/service_thread.h"
44#include "core/hle/result.h" 44#include "core/hle/result.h"
45#include "core/hle/service/server_manager.h"
45#include "core/hle/service/sm/sm.h" 46#include "core/hle/service/sm/sm.h"
46#include "core/memory.h" 47#include "core/memory.h"
47 48
@@ -55,9 +56,7 @@ struct KernelCore::Impl {
55 static constexpr size_t BlockInfoSlabHeapSize = 4000; 56 static constexpr size_t BlockInfoSlabHeapSize = 4000;
56 static constexpr size_t ReservedDynamicPageCount = 64; 57 static constexpr size_t ReservedDynamicPageCount = 64;
57 58
58 explicit Impl(Core::System& system_, KernelCore& kernel_) 59 explicit Impl(Core::System& system_, KernelCore& kernel_) : system{system_} {}
59 : service_threads_manager{1, "ServiceThreadsManager"},
60 service_thread_barrier{2}, system{system_} {}
61 60
62 void SetMulticore(bool is_multi) { 61 void SetMulticore(bool is_multi) {
63 is_multicore = is_multi; 62 is_multicore = is_multi;
@@ -98,8 +97,6 @@ struct KernelCore::Impl {
98 97
99 InitializeHackSharedMemory(); 98 InitializeHackSharedMemory();
100 RegisterHostThread(nullptr); 99 RegisterHostThread(nullptr);
101
102 default_service_thread = &CreateServiceThread(kernel, "DefaultServiceThread");
103 } 100 }
104 101
105 void InitializeCores() { 102 void InitializeCores() {
@@ -140,11 +137,6 @@ struct KernelCore::Impl {
140 137
141 preemption_event = nullptr; 138 preemption_event = nullptr;
142 139
143 for (auto& iter : named_ports) {
144 iter.second->Close();
145 }
146 named_ports.clear();
147
148 exclusive_monitor.reset(); 140 exclusive_monitor.reset();
149 141
150 // Cleanup persistent kernel objects 142 // Cleanup persistent kernel objects
@@ -207,8 +199,9 @@ struct KernelCore::Impl {
207 } 199 }
208 200
209 void CloseServices() { 201 void CloseServices() {
210 // Ensures all service threads gracefully shutdown. 202 // Ensures all servers gracefully shutdown.
211 ClearServiceThreads(); 203 std::scoped_lock lk{server_lock};
204 server_managers.clear();
212 } 205 }
213 206
214 void InitializePhysicalCores() { 207 void InitializePhysicalCores() {
@@ -761,55 +754,6 @@ struct KernelCore::Impl {
761 "HidBus:SharedMemory"); 754 "HidBus:SharedMemory");
762 } 755 }
763 756
764 KClientPort* CreateNamedServicePort(std::string name) {
765 auto search = service_interface_factory.find(name);
766 if (search == service_interface_factory.end()) {
767 UNIMPLEMENTED();
768 return {};
769 }
770
771 return &search->second(system.ServiceManager(), system);
772 }
773
774 void RegisterNamedServiceHandler(std::string name, KServerPort* server_port) {
775 auto search = service_interface_handlers.find(name);
776 if (search == service_interface_handlers.end()) {
777 return;
778 }
779
780 search->second(system.ServiceManager(), server_port);
781 }
782
783 Kernel::ServiceThread& CreateServiceThread(KernelCore& kernel, const std::string& name) {
784 auto* ptr = new ServiceThread(kernel, name);
785
786 service_threads_manager.QueueWork(
787 [this, ptr]() { service_threads.emplace(ptr, std::unique_ptr<ServiceThread>(ptr)); });
788
789 return *ptr;
790 }
791
792 void ReleaseServiceThread(Kernel::ServiceThread& service_thread) {
793 auto* ptr = &service_thread;
794
795 if (ptr == default_service_thread) {
796 // Nothing to do here, the service is using default_service_thread, which will be
797 // released on shutdown.
798 return;
799 }
800
801 service_threads_manager.QueueWork([this, ptr]() { service_threads.erase(ptr); });
802 }
803
804 void ClearServiceThreads() {
805 service_threads_manager.QueueWork([this] {
806 service_threads.clear();
807 default_service_thread = nullptr;
808 service_thread_barrier.Sync();
809 });
810 service_thread_barrier.Sync();
811 }
812
813 std::mutex registered_objects_lock; 757 std::mutex registered_objects_lock;
814 std::mutex registered_in_use_objects_lock; 758 std::mutex registered_in_use_objects_lock;
815 759
@@ -839,14 +783,12 @@ struct KernelCore::Impl {
839 783
840 std::unique_ptr<KObjectNameGlobalData> object_name_global_data; 784 std::unique_ptr<KObjectNameGlobalData> object_name_global_data;
841 785
842 /// Map of named ports managed by the kernel, which can be retrieved using
843 /// the ConnectToPort SVC.
844 std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory;
845 std::unordered_map<std::string, ServiceInterfaceHandlerFn> service_interface_handlers;
846 NamedPortTable named_ports;
847 std::unordered_set<KAutoObject*> registered_objects; 786 std::unordered_set<KAutoObject*> registered_objects;
848 std::unordered_set<KAutoObject*> registered_in_use_objects; 787 std::unordered_set<KAutoObject*> registered_in_use_objects;
849 788
789 std::mutex server_lock;
790 std::vector<std::unique_ptr<Service::ServerManager>> server_managers;
791
850 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; 792 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
851 std::array<std::unique_ptr<Kernel::PhysicalCore>, Core::Hardware::NUM_CPU_CORES> cores; 793 std::array<std::unique_ptr<Kernel::PhysicalCore>, Core::Hardware::NUM_CPU_CORES> cores;
852 794
@@ -881,12 +823,6 @@ struct KernelCore::Impl {
881 // Memory layout 823 // Memory layout
882 std::unique_ptr<KMemoryLayout> memory_layout; 824 std::unique_ptr<KMemoryLayout> memory_layout;
883 825
884 // Threads used for services
885 std::unordered_map<ServiceThread*, std::unique_ptr<ServiceThread>> service_threads;
886 ServiceThread* default_service_thread{};
887 Common::ThreadWorker service_threads_manager;
888 Common::Barrier service_thread_barrier;
889
890 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads{}; 826 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads{};
891 std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; 827 std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
892 828
@@ -1050,23 +986,6 @@ void KernelCore::PrepareReschedule(std::size_t id) {
1050 // TODO: Reimplement, this 986 // TODO: Reimplement, this
1051} 987}
1052 988
1053void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory) {
1054 impl->service_interface_factory.emplace(std::move(name), factory);
1055}
1056
1057void KernelCore::RegisterInterfaceForNamedService(std::string name,
1058 ServiceInterfaceHandlerFn&& handler) {
1059 impl->service_interface_handlers.emplace(std::move(name), handler);
1060}
1061
1062KClientPort* KernelCore::CreateNamedServicePort(std::string name) {
1063 return impl->CreateNamedServicePort(std::move(name));
1064}
1065
1066void KernelCore::RegisterNamedServiceHandler(std::string name, KServerPort* server_port) {
1067 impl->RegisterNamedServiceHandler(std::move(name), server_port);
1068}
1069
1070void KernelCore::RegisterKernelObject(KAutoObject* object) { 989void KernelCore::RegisterKernelObject(KAutoObject* object) {
1071 std::scoped_lock lk{impl->registered_objects_lock}; 990 std::scoped_lock lk{impl->registered_objects_lock};
1072 impl->registered_objects.insert(object); 991 impl->registered_objects.insert(object);
@@ -1087,8 +1006,19 @@ void KernelCore::UnregisterInUseObject(KAutoObject* object) {
1087 impl->registered_in_use_objects.erase(object); 1006 impl->registered_in_use_objects.erase(object);
1088} 1007}
1089 1008
1090bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { 1009void KernelCore::RunServer(std::unique_ptr<Service::ServerManager>&& server_manager) {
1091 return port != impl->named_ports.cend(); 1010 auto* manager = server_manager.get();
1011
1012 {
1013 std::scoped_lock lk{impl->server_lock};
1014 if (impl->is_shutting_down) {
1015 return;
1016 }
1017
1018 impl->server_managers.emplace_back(std::move(server_manager));
1019 }
1020
1021 manager->LoopProcess();
1092} 1022}
1093 1023
1094u32 KernelCore::CreateNewObjectID() { 1024u32 KernelCore::CreateNewObjectID() {
@@ -1127,6 +1057,87 @@ void KernelCore::RegisterHostThread(KThread* existing_thread) {
1127 } 1057 }
1128} 1058}
1129 1059
1060static std::jthread RunHostThreadFunc(KernelCore& kernel, KProcess* process,
1061 std::string&& thread_name, std::function<void()>&& func) {
1062 // Reserve a new thread from the process resource limit.
1063 KScopedResourceReservation thread_reservation(process, LimitableResource::ThreadCountMax);
1064 ASSERT(thread_reservation.Succeeded());
1065
1066 // Initialize the thread.
1067 KThread* thread = KThread::Create(kernel);
1068 ASSERT(R_SUCCEEDED(KThread::InitializeDummyThread(thread, process)));
1069
1070 // Commit the thread reservation.
1071 thread_reservation.Commit();
1072
1073 return std::jthread(
1074 [&kernel, thread, thread_name{std::move(thread_name)}, func{std::move(func)}] {
1075 // Set the thread name.
1076 Common::SetCurrentThreadName(thread_name.c_str());
1077
1078 // Register the thread.
1079 kernel.RegisterHostThread(thread);
1080
1081 // Run the callback.
1082 func();
1083
1084 // Close the thread.
1085 // This will free the process if it is the last reference.
1086 thread->Close();
1087 });
1088}
1089
1090std::jthread KernelCore::RunOnHostCoreProcess(std::string&& process_name,
1091 std::function<void()> func) {
1092 // Make a new process.
1093 KProcess* process = KProcess::Create(*this);
1094 ASSERT(R_SUCCEEDED(KProcess::Initialize(process, System(), "", KProcess::ProcessType::Userland,
1095 GetSystemResourceLimit())));
1096
1097 // Ensure that we don't hold onto any extra references.
1098 SCOPE_EXIT({ process->Close(); });
1099
1100 // Run the host thread.
1101 return RunHostThreadFunc(*this, process, std::move(process_name), std::move(func));
1102}
1103
1104std::jthread KernelCore::RunOnHostCoreThread(std::string&& thread_name,
1105 std::function<void()> func) {
1106 // Get the current process.
1107 KProcess* process = GetCurrentProcessPointer(*this);
1108
1109 // Run the host thread.
1110 return RunHostThreadFunc(*this, process, std::move(thread_name), std::move(func));
1111}
1112
1113void KernelCore::RunOnGuestCoreProcess(std::string&& process_name, std::function<void()> func) {
1114 constexpr s32 ServiceThreadPriority = 16;
1115 constexpr s32 ServiceThreadCore = 3;
1116
1117 // Make a new process.
1118 KProcess* process = KProcess::Create(*this);
1119 ASSERT(R_SUCCEEDED(KProcess::Initialize(process, System(), "", KProcess::ProcessType::Userland,
1120 GetSystemResourceLimit())));
1121
1122 // Ensure that we don't hold onto any extra references.
1123 SCOPE_EXIT({ process->Close(); });
1124
1125 // Reserve a new thread from the process resource limit.
1126 KScopedResourceReservation thread_reservation(process, LimitableResource::ThreadCountMax);
1127 ASSERT(thread_reservation.Succeeded());
1128
1129 // Initialize the thread.
1130 KThread* thread = KThread::Create(*this);
1131 ASSERT(R_SUCCEEDED(KThread::InitializeServiceThread(
1132 System(), thread, std::move(func), ServiceThreadPriority, ServiceThreadCore, process)));
1133
1134 // Commit the thread reservation.
1135 thread_reservation.Commit();
1136
1137 // Begin running the thread.
1138 ASSERT(R_SUCCEEDED(thread->Run()));
1139}
1140
1130u32 KernelCore::GetCurrentHostThreadID() const { 1141u32 KernelCore::GetCurrentHostThreadID() const {
1131 return impl->GetCurrentHostThreadID(); 1142 return impl->GetCurrentHostThreadID();
1132} 1143}
@@ -1271,18 +1282,6 @@ void KernelCore::ExitSVCProfile() {
1271 MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]); 1282 MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]);
1272} 1283}
1273 1284
1274Kernel::ServiceThread& KernelCore::CreateServiceThread(const std::string& name) {
1275 return impl->CreateServiceThread(*this, name);
1276}
1277
1278Kernel::ServiceThread& KernelCore::GetDefaultServiceThread() const {
1279 return *impl->default_service_thread;
1280}
1281
1282void KernelCore::ReleaseServiceThread(Kernel::ServiceThread& service_thread) {
1283 impl->ReleaseServiceThread(service_thread);
1284}
1285
1286Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() { 1285Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() {
1287 return impl->slab_resource_counts; 1286 return impl->slab_resource_counts;
1288} 1287}
@@ -1319,4 +1318,97 @@ const Core::System& KernelCore::System() const {
1319 return impl->system; 1318 return impl->system;
1320} 1319}
1321 1320
1321struct KernelCore::SlabHeapContainer {
1322 KSlabHeap<KClientSession> client_session;
1323 KSlabHeap<KEvent> event;
1324 KSlabHeap<KLinkedListNode> linked_list_node;
1325 KSlabHeap<KPort> port;
1326 KSlabHeap<KProcess> process;
1327 KSlabHeap<KResourceLimit> resource_limit;
1328 KSlabHeap<KSession> session;
1329 KSlabHeap<KSharedMemory> shared_memory;
1330 KSlabHeap<KSharedMemoryInfo> shared_memory_info;
1331 KSlabHeap<KThread> thread;
1332 KSlabHeap<KTransferMemory> transfer_memory;
1333 KSlabHeap<KCodeMemory> code_memory;
1334 KSlabHeap<KDeviceAddressSpace> device_address_space;
1335 KSlabHeap<KPageBuffer> page_buffer;
1336 KSlabHeap<KThreadLocalPage> thread_local_page;
1337 KSlabHeap<KObjectName> object_name;
1338 KSlabHeap<KSessionRequest> session_request;
1339 KSlabHeap<KSecureSystemResource> secure_system_resource;
1340 KSlabHeap<KThread::LockWithPriorityInheritanceInfo> lock_info;
1341 KSlabHeap<KEventInfo> event_info;
1342 KSlabHeap<KDebug> debug;
1343};
1344
1345template <typename T>
1346KSlabHeap<T>& KernelCore::SlabHeap() {
1347 if constexpr (std::is_same_v<T, KClientSession>) {
1348 return slab_heap_container->client_session;
1349 } else if constexpr (std::is_same_v<T, KEvent>) {
1350 return slab_heap_container->event;
1351 } else if constexpr (std::is_same_v<T, KLinkedListNode>) {
1352 return slab_heap_container->linked_list_node;
1353 } else if constexpr (std::is_same_v<T, KPort>) {
1354 return slab_heap_container->port;
1355 } else if constexpr (std::is_same_v<T, KProcess>) {
1356 return slab_heap_container->process;
1357 } else if constexpr (std::is_same_v<T, KResourceLimit>) {
1358 return slab_heap_container->resource_limit;
1359 } else if constexpr (std::is_same_v<T, KSession>) {
1360 return slab_heap_container->session;
1361 } else if constexpr (std::is_same_v<T, KSharedMemory>) {
1362 return slab_heap_container->shared_memory;
1363 } else if constexpr (std::is_same_v<T, KSharedMemoryInfo>) {
1364 return slab_heap_container->shared_memory_info;
1365 } else if constexpr (std::is_same_v<T, KThread>) {
1366 return slab_heap_container->thread;
1367 } else if constexpr (std::is_same_v<T, KTransferMemory>) {
1368 return slab_heap_container->transfer_memory;
1369 } else if constexpr (std::is_same_v<T, KCodeMemory>) {
1370 return slab_heap_container->code_memory;
1371 } else if constexpr (std::is_same_v<T, KDeviceAddressSpace>) {
1372 return slab_heap_container->device_address_space;
1373 } else if constexpr (std::is_same_v<T, KPageBuffer>) {
1374 return slab_heap_container->page_buffer;
1375 } else if constexpr (std::is_same_v<T, KThreadLocalPage>) {
1376 return slab_heap_container->thread_local_page;
1377 } else if constexpr (std::is_same_v<T, KObjectName>) {
1378 return slab_heap_container->object_name;
1379 } else if constexpr (std::is_same_v<T, KSessionRequest>) {
1380 return slab_heap_container->session_request;
1381 } else if constexpr (std::is_same_v<T, KSecureSystemResource>) {
1382 return slab_heap_container->secure_system_resource;
1383 } else if constexpr (std::is_same_v<T, KThread::LockWithPriorityInheritanceInfo>) {
1384 return slab_heap_container->lock_info;
1385 } else if constexpr (std::is_same_v<T, KEventInfo>) {
1386 return slab_heap_container->event_info;
1387 } else if constexpr (std::is_same_v<T, KDebug>) {
1388 return slab_heap_container->debug;
1389 }
1390}
1391
1392template KSlabHeap<KClientSession>& KernelCore::SlabHeap();
1393template KSlabHeap<KEvent>& KernelCore::SlabHeap();
1394template KSlabHeap<KLinkedListNode>& KernelCore::SlabHeap();
1395template KSlabHeap<KPort>& KernelCore::SlabHeap();
1396template KSlabHeap<KProcess>& KernelCore::SlabHeap();
1397template KSlabHeap<KResourceLimit>& KernelCore::SlabHeap();
1398template KSlabHeap<KSession>& KernelCore::SlabHeap();
1399template KSlabHeap<KSharedMemory>& KernelCore::SlabHeap();
1400template KSlabHeap<KSharedMemoryInfo>& KernelCore::SlabHeap();
1401template KSlabHeap<KThread>& KernelCore::SlabHeap();
1402template KSlabHeap<KTransferMemory>& KernelCore::SlabHeap();
1403template KSlabHeap<KCodeMemory>& KernelCore::SlabHeap();
1404template KSlabHeap<KDeviceAddressSpace>& KernelCore::SlabHeap();
1405template KSlabHeap<KPageBuffer>& KernelCore::SlabHeap();
1406template KSlabHeap<KThreadLocalPage>& KernelCore::SlabHeap();
1407template KSlabHeap<KObjectName>& KernelCore::SlabHeap();
1408template KSlabHeap<KSessionRequest>& KernelCore::SlabHeap();
1409template KSlabHeap<KSecureSystemResource>& KernelCore::SlabHeap();
1410template KSlabHeap<KThread::LockWithPriorityInheritanceInfo>& KernelCore::SlabHeap();
1411template KSlabHeap<KEventInfo>& KernelCore::SlabHeap();
1412template KSlabHeap<KDebug>& KernelCore::SlabHeap();
1413
1322} // namespace Kernel 1414} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 6e0668f7f..1b380a07b 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -9,6 +9,8 @@
9#include <string> 9#include <string>
10#include <unordered_map> 10#include <unordered_map>
11#include <vector> 11#include <vector>
12
13#include "common/polyfill_thread.h"
12#include "core/hardware_properties.h" 14#include "core/hardware_properties.h"
13#include "core/hle/kernel/k_auto_object.h" 15#include "core/hle/kernel/k_auto_object.h"
14#include "core/hle/kernel/k_slab_heap.h" 16#include "core/hle/kernel/k_slab_heap.h"
@@ -24,6 +26,10 @@ class CoreTiming;
24struct EventType; 26struct EventType;
25} // namespace Core::Timing 27} // namespace Core::Timing
26 28
29namespace Service {
30class ServerManager;
31}
32
27namespace Service::SM { 33namespace Service::SM {
28class ServiceManager; 34class ServiceManager;
29} 35}
@@ -65,13 +71,6 @@ class KTransferMemory;
65class KWorkerTaskManager; 71class KWorkerTaskManager;
66class KCodeMemory; 72class KCodeMemory;
67class PhysicalCore; 73class PhysicalCore;
68class ServiceThread;
69class Synchronization;
70
71using ServiceInterfaceFactory =
72 std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>;
73
74using ServiceInterfaceHandlerFn = std::function<void(Service::SM::ServiceManager&, KServerPort*)>;
75 74
76namespace Init { 75namespace Init {
77struct KSlabResourceCounts; 76struct KSlabResourceCounts;
@@ -80,15 +79,8 @@ struct KSlabResourceCounts;
80template <typename T> 79template <typename T>
81class KSlabHeap; 80class KSlabHeap;
82 81
83using EmuThreadHandle = uintptr_t;
84constexpr EmuThreadHandle EmuThreadHandleInvalid{};
85constexpr EmuThreadHandle EmuThreadHandleReserved{1ULL << 63};
86
87/// Represents a single instance of the kernel. 82/// Represents a single instance of the kernel.
88class KernelCore { 83class KernelCore {
89private:
90 using NamedPortTable = std::unordered_map<std::string, KClientPort*>;
91
92public: 84public:
93 /// Constructs an instance of the kernel using the given System 85 /// Constructs an instance of the kernel using the given System
94 /// instance as a context for any necessary system-related state, 86 /// instance as a context for any necessary system-related state,
@@ -196,18 +188,6 @@ public:
196 188
197 void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); 189 void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
198 190
199 /// Registers a named HLE service, passing a factory used to open a port to that service.
200 void RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory);
201
202 /// Registers a setup function for the named HLE service.
203 void RegisterInterfaceForNamedService(std::string name, ServiceInterfaceHandlerFn&& handler);
204
205 /// Opens a port to a service previously registered with RegisterNamedService.
206 KClientPort* CreateNamedServicePort(std::string name);
207
208 /// Accepts a session on a port created by CreateNamedServicePort.
209 void RegisterNamedServiceHandler(std::string name, KServerPort* server_port);
210
211 /// Registers all kernel objects with the global emulation state, this is purely for tracking 191 /// Registers all kernel objects with the global emulation state, this is purely for tracking
212 /// leaks after emulation has been shutdown. 192 /// leaks after emulation has been shutdown.
213 void RegisterKernelObject(KAutoObject* object); 193 void RegisterKernelObject(KAutoObject* object);
@@ -224,8 +204,8 @@ public:
224 /// destroyed during the current emulation session. 204 /// destroyed during the current emulation session.
225 void UnregisterInUseObject(KAutoObject* object); 205 void UnregisterInUseObject(KAutoObject* object);
226 206
227 /// Determines whether or not the given port is a valid named port. 207 // Runs the given server manager until shutdown.
228 bool IsValidNamedPort(NamedPortTable::const_iterator port) const; 208 void RunServer(std::unique_ptr<Service::ServerManager>&& server_manager);
229 209
230 /// Gets the current host_thread/guest_thread pointer. 210 /// Gets the current host_thread/guest_thread pointer.
231 KThread* GetCurrentEmuThread() const; 211 KThread* GetCurrentEmuThread() const;
@@ -242,6 +222,12 @@ public:
242 /// Register the current thread as a non CPU core thread. 222 /// Register the current thread as a non CPU core thread.
243 void RegisterHostThread(KThread* existing_thread = nullptr); 223 void RegisterHostThread(KThread* existing_thread = nullptr);
244 224
225 void RunOnGuestCoreProcess(std::string&& process_name, std::function<void()> func);
226
227 std::jthread RunOnHostCoreProcess(std::string&& process_name, std::function<void()> func);
228
229 std::jthread RunOnHostCoreThread(std::string&& thread_name, std::function<void()> func);
230
245 /// Gets global data for KObjectName. 231 /// Gets global data for KObjectName.
246 KObjectNameGlobalData& ObjectNameGlobalData(); 232 KObjectNameGlobalData& ObjectNameGlobalData();
247 233
@@ -310,33 +296,6 @@ public:
310 296
311 void ExitSVCProfile(); 297 void ExitSVCProfile();
312 298
313 /**
314 * Creates a host thread to execute HLE service requests, which are used to execute service
315 * routines asynchronously. While these are allocated per ServerSession, these need to be owned
316 * and managed outside of ServerSession to avoid a circular dependency. In general, most
317 * services can just use the default service thread, and not need their own host service thread.
318 * See GetDefaultServiceThread.
319 * @param name String name for the ServerSession creating this thread, used for debug
320 * purposes.
321 * @returns A reference to the newly created service thread.
322 */
323 Kernel::ServiceThread& CreateServiceThread(const std::string& name);
324
325 /**
326 * Gets the default host service thread, which executes HLE service requests. Unless service
327 * requests need to block on the host, the default service thread should be used in favor of
328 * creating a new service thread.
329 * @returns A reference to the default service thread.
330 */
331 Kernel::ServiceThread& GetDefaultServiceThread() const;
332
333 /**
334 * Releases a HLE service thread, instructing KernelCore to free it. This should be called when
335 * the ServerSession associated with the thread is destroyed.
336 * @param service_thread Service thread to release.
337 */
338 void ReleaseServiceThread(Kernel::ServiceThread& service_thread);
339
340 /// Workaround for single-core mode when preempting threads while idle. 299 /// Workaround for single-core mode when preempting threads while idle.
341 bool IsPhantomModeForSingleCore() const; 300 bool IsPhantomModeForSingleCore() const;
342 void SetIsPhantomModeForSingleCore(bool value); 301 void SetIsPhantomModeForSingleCore(bool value);
@@ -346,49 +305,7 @@ public:
346 305
347 /// Gets the slab heap for the specified kernel object type. 306 /// Gets the slab heap for the specified kernel object type.
348 template <typename T> 307 template <typename T>
349 KSlabHeap<T>& SlabHeap() { 308 KSlabHeap<T>& SlabHeap();
350 if constexpr (std::is_same_v<T, KClientSession>) {
351 return slab_heap_container->client_session;
352 } else if constexpr (std::is_same_v<T, KEvent>) {
353 return slab_heap_container->event;
354 } else if constexpr (std::is_same_v<T, KLinkedListNode>) {
355 return slab_heap_container->linked_list_node;
356 } else if constexpr (std::is_same_v<T, KPort>) {
357 return slab_heap_container->port;
358 } else if constexpr (std::is_same_v<T, KProcess>) {
359 return slab_heap_container->process;
360 } else if constexpr (std::is_same_v<T, KResourceLimit>) {
361 return slab_heap_container->resource_limit;
362 } else if constexpr (std::is_same_v<T, KSession>) {
363 return slab_heap_container->session;
364 } else if constexpr (std::is_same_v<T, KSharedMemory>) {
365 return slab_heap_container->shared_memory;
366 } else if constexpr (std::is_same_v<T, KSharedMemoryInfo>) {
367 return slab_heap_container->shared_memory_info;
368 } else if constexpr (std::is_same_v<T, KThread>) {
369 return slab_heap_container->thread;
370 } else if constexpr (std::is_same_v<T, KTransferMemory>) {
371 return slab_heap_container->transfer_memory;
372 } else if constexpr (std::is_same_v<T, KCodeMemory>) {
373 return slab_heap_container->code_memory;
374 } else if constexpr (std::is_same_v<T, KDeviceAddressSpace>) {
375 return slab_heap_container->device_address_space;
376 } else if constexpr (std::is_same_v<T, KPageBuffer>) {
377 return slab_heap_container->page_buffer;
378 } else if constexpr (std::is_same_v<T, KThreadLocalPage>) {
379 return slab_heap_container->thread_local_page;
380 } else if constexpr (std::is_same_v<T, KObjectName>) {
381 return slab_heap_container->object_name;
382 } else if constexpr (std::is_same_v<T, KSessionRequest>) {
383 return slab_heap_container->session_request;
384 } else if constexpr (std::is_same_v<T, KSecureSystemResource>) {
385 return slab_heap_container->secure_system_resource;
386 } else if constexpr (std::is_same_v<T, KEventInfo>) {
387 return slab_heap_container->event_info;
388 } else if constexpr (std::is_same_v<T, KDebug>) {
389 return slab_heap_container->debug;
390 }
391 }
392 309
393 /// Gets the current slab resource counts. 310 /// Gets the current slab resource counts.
394 Init::KSlabResourceCounts& SlabResourceCounts(); 311 Init::KSlabResourceCounts& SlabResourceCounts();
@@ -434,28 +351,7 @@ private:
434 351
435private: 352private:
436 /// Helper to encapsulate all slab heaps in a single heap allocated container 353 /// Helper to encapsulate all slab heaps in a single heap allocated container
437 struct SlabHeapContainer { 354 struct SlabHeapContainer;
438 KSlabHeap<KClientSession> client_session;
439 KSlabHeap<KEvent> event;
440 KSlabHeap<KLinkedListNode> linked_list_node;
441 KSlabHeap<KPort> port;
442 KSlabHeap<KProcess> process;
443 KSlabHeap<KResourceLimit> resource_limit;
444 KSlabHeap<KSession> session;
445 KSlabHeap<KSharedMemory> shared_memory;
446 KSlabHeap<KSharedMemoryInfo> shared_memory_info;
447 KSlabHeap<KThread> thread;
448 KSlabHeap<KTransferMemory> transfer_memory;
449 KSlabHeap<KCodeMemory> code_memory;
450 KSlabHeap<KDeviceAddressSpace> device_address_space;
451 KSlabHeap<KPageBuffer> page_buffer;
452 KSlabHeap<KThreadLocalPage> thread_local_page;
453 KSlabHeap<KObjectName> object_name;
454 KSlabHeap<KSessionRequest> session_request;
455 KSlabHeap<KSecureSystemResource> secure_system_resource;
456 KSlabHeap<KEventInfo> event_info;
457 KSlabHeap<KDebug> debug;
458 };
459 355
460 std::unique_ptr<SlabHeapContainer> slab_heap_container; 356 std::unique_ptr<SlabHeapContainer> slab_heap_container;
461}; 357};
diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp
deleted file mode 100644
index 38afa720b..000000000
--- a/src/core/hle/kernel/service_thread.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <functional>
5#include <map>
6#include <mutex>
7#include <thread>
8#include <vector>
9
10#include "common/polyfill_thread.h"
11#include "common/scope_exit.h"
12#include "common/thread.h"
13#include "core/hle/ipc_helpers.h"
14#include "core/hle/kernel/hle_ipc.h"
15#include "core/hle/kernel/k_event.h"
16#include "core/hle/kernel/k_scoped_resource_reservation.h"
17#include "core/hle/kernel/k_session.h"
18#include "core/hle/kernel/k_thread.h"
19#include "core/hle/kernel/kernel.h"
20#include "core/hle/kernel/service_thread.h"
21
22namespace Kernel {
23
24class ServiceThread::Impl final {
25public:
26 explicit Impl(KernelCore& kernel, const std::string& service_name);
27 ~Impl();
28
29 void WaitAndProcessImpl();
30 void SessionClosed(KServerSession* server_session,
31 std::shared_ptr<SessionRequestManager> manager);
32 void LoopProcess();
33
34 void RegisterServerSession(KServerSession* session,
35 std::shared_ptr<SessionRequestManager> manager);
36
37private:
38 KernelCore& kernel;
39 const std::string m_service_name;
40
41 std::jthread m_host_thread{};
42 std::mutex m_session_mutex{};
43 std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions{};
44 KEvent* m_wakeup_event{};
45 KThread* m_thread{};
46 std::atomic<bool> m_shutdown_requested{};
47};
48
49void ServiceThread::Impl::WaitAndProcessImpl() {
50 // Create local list of waitable sessions.
51 std::vector<KSynchronizationObject*> objs;
52 std::vector<std::shared_ptr<SessionRequestManager>> managers;
53
54 {
55 // Lock to get the set.
56 std::scoped_lock lk{m_session_mutex};
57
58 // Reserve the needed quantity.
59 objs.reserve(m_sessions.size() + 1);
60 managers.reserve(m_sessions.size());
61
62 // Copy to our local list.
63 for (const auto& [session, manager] : m_sessions) {
64 objs.push_back(session);
65 managers.push_back(manager);
66 }
67
68 // Insert the wakeup event at the end.
69 objs.push_back(&m_wakeup_event->GetReadableEvent());
70 }
71
72 // Wait on the list of sessions.
73 s32 index{-1};
74 Result rc = KSynchronizationObject::Wait(kernel, &index, objs.data(),
75 static_cast<s32>(objs.size()), -1);
76 ASSERT(!rc.IsFailure());
77
78 // If this was the wakeup event, clear it and finish.
79 if (index >= static_cast<s64>(objs.size() - 1)) {
80 m_wakeup_event->Clear();
81 return;
82 }
83
84 // This event is from a server session.
85 auto* server_session = static_cast<KServerSession*>(objs[index]);
86 auto& manager = managers[index];
87
88 // Fetch the HLE request context.
89 std::shared_ptr<HLERequestContext> context;
90 rc = server_session->ReceiveRequest(&context, manager);
91
92 // If the session was closed, handle that.
93 if (rc == ResultSessionClosed) {
94 SessionClosed(server_session, manager);
95
96 // Finish.
97 return;
98 }
99
100 // TODO: handle other cases
101 ASSERT(rc == ResultSuccess);
102
103 // Perform the request.
104 Result service_rc = manager->CompleteSyncRequest(server_session, *context);
105
106 // Reply to the client.
107 rc = server_session->SendReplyHLE();
108
109 if (rc == ResultSessionClosed || service_rc == IPC::ERR_REMOTE_PROCESS_DEAD) {
110 SessionClosed(server_session, manager);
111 return;
112 }
113
114 // TODO: handle other cases
115 ASSERT(rc == ResultSuccess);
116 ASSERT(service_rc == ResultSuccess);
117}
118
119void ServiceThread::Impl::SessionClosed(KServerSession* server_session,
120 std::shared_ptr<SessionRequestManager> manager) {
121 {
122 // Lock to get the set.
123 std::scoped_lock lk{m_session_mutex};
124
125 // Erase the session.
126 ASSERT(m_sessions.erase(server_session) == 1);
127 }
128
129 // Close our reference to the server session.
130 server_session->Close();
131}
132
133void ServiceThread::Impl::LoopProcess() {
134 Common::SetCurrentThreadName(m_service_name.c_str());
135
136 kernel.RegisterHostThread(m_thread);
137
138 while (!m_shutdown_requested.load()) {
139 WaitAndProcessImpl();
140 }
141}
142
143void ServiceThread::Impl::RegisterServerSession(KServerSession* server_session,
144 std::shared_ptr<SessionRequestManager> manager) {
145 // Open the server session.
146 server_session->Open();
147
148 {
149 // Lock to get the set.
150 std::scoped_lock lk{m_session_mutex};
151
152 // Insert the session and manager.
153 m_sessions[server_session] = manager;
154 }
155
156 // Signal the wakeup event.
157 m_wakeup_event->Signal();
158}
159
160ServiceThread::Impl::~Impl() {
161 // Shut down the processing thread.
162 m_shutdown_requested.store(true);
163 m_wakeup_event->Signal();
164 m_host_thread.join();
165
166 // Close all remaining sessions.
167 for (const auto& [server_session, manager] : m_sessions) {
168 server_session->Close();
169 }
170
171 // Destroy remaining managers.
172 m_sessions.clear();
173
174 // Close event.
175 m_wakeup_event->GetReadableEvent().Close();
176 m_wakeup_event->Close();
177
178 // Close thread.
179 m_thread->Close();
180}
181
182ServiceThread::Impl::Impl(KernelCore& kernel_, const std::string& service_name)
183 : kernel{kernel_}, m_service_name{service_name} {
184 // Initialize event.
185 m_wakeup_event = KEvent::Create(kernel);
186 m_wakeup_event->Initialize(nullptr);
187
188 // Initialize thread.
189 m_thread = KThread::Create(kernel);
190 ASSERT(KThread::InitializeDummyThread(m_thread, nullptr).IsSuccess());
191
192 // Start thread.
193 m_host_thread = std::jthread([this] { LoopProcess(); });
194}
195
196ServiceThread::ServiceThread(KernelCore& kernel, const std::string& name)
197 : impl{std::make_unique<Impl>(kernel, name)} {}
198
199ServiceThread::~ServiceThread() = default;
200
201void ServiceThread::RegisterServerSession(KServerSession* session,
202 std::shared_ptr<SessionRequestManager> manager) {
203 impl->RegisterServerSession(session, manager);
204}
205
206} // namespace Kernel
diff --git a/src/core/hle/kernel/service_thread.h b/src/core/hle/kernel/service_thread.h
deleted file mode 100644
index fb4325531..000000000
--- a/src/core/hle/kernel/service_thread.h
+++ /dev/null
@@ -1,29 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <memory>
7#include <string>
8
9namespace Kernel {
10
11class HLERequestContext;
12class KernelCore;
13class KSession;
14class SessionRequestManager;
15
16class ServiceThread final {
17public:
18 explicit ServiceThread(KernelCore& kernel, const std::string& name);
19 ~ServiceThread();
20
21 void RegisterServerSession(KServerSession* session,
22 std::shared_ptr<SessionRequestManager> manager);
23
24private:
25 class Impl;
26 std::unique_ptr<Impl> impl;
27};
28
29} // namespace Kernel
diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp
index 58dc47508..cbed4dc8c 100644
--- a/src/core/hle/kernel/svc/svc_info.cpp
+++ b/src/core/hle/kernel/svc/svc_info.cpp
@@ -126,6 +126,11 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
126 *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource(); 126 *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource();
127 return ResultSuccess; 127 return ResultSuccess;
128 128
129 case InfoType::IsApplication:
130 LOG_WARNING(Kernel_SVC, "(STUBBED) Assuming process is application");
131 *result = true;
132 return ResultSuccess;
133
129 case InfoType::FreeThreadCount: 134 case InfoType::FreeThreadCount:
130 *result = process->GetFreeThreadCount(); 135 *result = process->GetFreeThreadCount();
131 return ResultSuccess; 136 return ResultSuccess;
diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp
index 0b5b4ba2b..78c2a8d17 100644
--- a/src/core/hle/kernel/svc/svc_port.cpp
+++ b/src/core/hle/kernel/svc/svc_port.cpp
@@ -12,56 +12,40 @@
12 12
13namespace Kernel::Svc { 13namespace Kernel::Svc {
14 14
15/// Connect to an OS service given the port name, returns the handle to the port to out 15Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr user_name) {
16Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { 16 // Copy the provided name from user memory to kernel memory.
17 auto& memory = system.Memory(); 17 auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax);
18 if (!memory.IsValidVirtualAddress(port_name_address)) {
19 LOG_ERROR(Kernel_SVC,
20 "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}",
21 port_name_address);
22 return ResultNotFound;
23 }
24 18
25 static constexpr std::size_t PortNameMaxLength = 11; 19 std::array<char, KObjectName::NameLengthMax> name{};
26 // Read 1 char beyond the max allowed port name to detect names that are too long. 20 std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1);
27 const std::string port_name = memory.ReadCString(port_name_address, PortNameMaxLength + 1);
28 if (port_name.size() > PortNameMaxLength) {
29 LOG_ERROR(Kernel_SVC, "Port name is too long, expected {} but got {}", PortNameMaxLength,
30 port_name.size());
31 return ResultOutOfRange;
32 }
33 21
34 LOG_TRACE(Kernel_SVC, "called port_name={}", port_name); 22 // Validate that the name is valid.
23 R_UNLESS(name[sizeof(name) - 1] == '\x00', ResultOutOfRange);
35 24
36 // Get the current handle table. 25 // Get the current handle table.
37 auto& kernel = system.Kernel(); 26 auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
38 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
39 27
40 // Find the client port. 28 // Find the client port.
41 auto port = kernel.CreateNamedServicePort(port_name); 29 auto port = KObjectName::Find<KClientPort>(system.Kernel(), name.data());
42 if (!port) { 30 R_UNLESS(port.IsNotNull(), ResultNotFound);
43 LOG_ERROR(Kernel_SVC, "tried to connect to unknown port: {}", port_name);
44 return ResultNotFound;
45 }
46 31
47 // Reserve a handle for the port. 32 // Reserve a handle for the port.
48 // NOTE: Nintendo really does write directly to the output handle here. 33 // NOTE: Nintendo really does write directly to the output handle here.
49 R_TRY(handle_table.Reserve(out)); 34 R_TRY(handle_table.Reserve(out));
50 auto handle_guard = SCOPE_GUARD({ handle_table.Unreserve(*out); }); 35 ON_RESULT_FAILURE {
36 handle_table.Unreserve(*out);
37 };
51 38
52 // Create a session. 39 // Create a session.
53 KClientSession* session{}; 40 KClientSession* session;
54 R_TRY(port->CreateSession(std::addressof(session))); 41 R_TRY(port->CreateSession(std::addressof(session)));
55 42
56 kernel.RegisterNamedServiceHandler(port_name, &port->GetParent()->GetServerPort());
57
58 // Register the session in the table, close the extra reference. 43 // Register the session in the table, close the extra reference.
59 handle_table.Register(*out, session); 44 handle_table.Register(*out, session);
60 session->Close(); 45 session->Close();
61 46
62 // We succeeded. 47 // We succeeded.
63 handle_guard.Cancel(); 48 R_SUCCEED();
64 return ResultSuccess;
65} 49}
66 50
67Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client, 51Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client,
@@ -78,8 +62,11 @@ Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) {
78Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, 62Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,
79 int32_t max_sessions) { 63 int32_t max_sessions) {
80 // Copy the provided name from user memory to kernel memory. 64 // Copy the provided name from user memory to kernel memory.
65 auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax);
66
67 // Copy the provided name from user memory to kernel memory.
81 std::array<char, KObjectName::NameLengthMax> name{}; 68 std::array<char, KObjectName::NameLengthMax> name{};
82 system.Memory().ReadBlock(user_name, name.data(), sizeof(name)); 69 std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1);
83 70
84 // Validate that sessions and name are valid. 71 // Validate that sessions and name are valid.
85 R_UNLESS(max_sessions >= 0, ResultOutOfRange); 72 R_UNLESS(max_sessions >= 0, ResultOutOfRange);
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp
index 1a8f7e191..9e7bf9530 100644
--- a/src/core/hle/kernel/svc/svc_synchronization.cpp
+++ b/src/core/hle/kernel/svc/svc_synchronization.cpp
@@ -48,19 +48,15 @@ Result ResetSignal(Core::System& system, Handle handle) {
48 return ResultInvalidHandle; 48 return ResultInvalidHandle;
49} 49}
50 50
51/// Wait for the given handles to synchronize, timeout after the specified nanoseconds 51static Result WaitSynchronization(Core::System& system, int32_t* out_index, const Handle* handles,
52Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, s32 num_handles, 52 int32_t num_handles, int64_t timeout_ns) {
53 s64 nano_seconds) {
54 LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, num_handles={}, nano_seconds={}",
55 handles_address, num_handles, nano_seconds);
56
57 // Ensure number of handles is valid. 53 // Ensure number of handles is valid.
58 R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); 54 R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange);
59 55
56 // Get the synchronization context.
60 auto& kernel = system.Kernel(); 57 auto& kernel = system.Kernel();
58 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
61 std::vector<KSynchronizationObject*> objs(num_handles); 59 std::vector<KSynchronizationObject*> objs(num_handles);
62 const auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
63 Handle* handles = system.Memory().GetPointer<Handle>(handles_address);
64 60
65 // Copy user handles. 61 // Copy user handles.
66 if (num_handles > 0) { 62 if (num_handles > 0) {
@@ -68,21 +64,38 @@ Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_addre
68 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, 64 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles,
69 num_handles), 65 num_handles),
70 ResultInvalidHandle); 66 ResultInvalidHandle);
71 for (const auto& obj : objs) {
72 kernel.RegisterInUseObject(obj);
73 }
74 } 67 }
75 68
76 // Ensure handles are closed when we're done. 69 // Ensure handles are closed when we're done.
77 SCOPE_EXIT({ 70 SCOPE_EXIT({
78 for (s32 i = 0; i < num_handles; ++i) { 71 for (auto i = 0; i < num_handles; ++i) {
79 kernel.UnregisterInUseObject(objs[i]);
80 objs[i]->Close(); 72 objs[i]->Close();
81 } 73 }
82 }); 74 });
83 75
84 return KSynchronizationObject::Wait(kernel, index, objs.data(), static_cast<s32>(objs.size()), 76 // Wait on the objects.
85 nano_seconds); 77 Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(),
78 static_cast<s32>(objs.size()), timeout_ns);
79
80 R_SUCCEED_IF(res == ResultSessionClosed);
81 R_RETURN(res);
82}
83
84/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
85Result WaitSynchronization(Core::System& system, int32_t* out_index, VAddr user_handles,
86 int32_t num_handles, int64_t timeout_ns) {
87 LOG_TRACE(Kernel_SVC, "called user_handles={:#x}, num_handles={}, timeout_ns={}", user_handles,
88 num_handles, timeout_ns);
89
90 // Ensure number of handles is valid.
91 R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange);
92
93 std::vector<Handle> handles(num_handles);
94 if (num_handles > 0) {
95 system.Memory().ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle));
96 }
97
98 R_RETURN(WaitSynchronization(system, out_index, handles.data(), num_handles, timeout_ns));
86} 99}
87 100
88/// Resumes a thread waiting on WaitSynchronization 101/// Resumes a thread waiting on WaitSynchronization
diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h
index 542c13461..39355d9c4 100644
--- a/src/core/hle/kernel/svc_types.h
+++ b/src/core/hle/kernel/svc_types.h
@@ -151,6 +151,7 @@ enum class InfoType : u32 {
151 FreeThreadCount = 24, 151 FreeThreadCount = 24,
152 ThreadTickCount = 25, 152 ThreadTickCount = 25,
153 IsSvcPermitted = 26, 153 IsSvcPermitted = 26,
154 IoRegionHint = 27,
154 155
155 MesosphereMeta = 65000, 156 MesosphereMeta = 65000,
156 MesosphereCurrentProcess = 65001, 157 MesosphereCurrentProcess = 65001,
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 1241fcdff..120282aa4 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -15,7 +15,6 @@
15#include "core/core_timing.h" 15#include "core/core_timing.h"
16#include "core/file_sys/control_metadata.h" 16#include "core/file_sys/control_metadata.h"
17#include "core/file_sys/patch_manager.h" 17#include "core/file_sys/patch_manager.h"
18#include "core/hle/ipc_helpers.h"
19#include "core/hle/service/acc/acc.h" 18#include "core/hle/service/acc/acc.h"
20#include "core/hle/service/acc/acc_aa.h" 19#include "core/hle/service/acc/acc_aa.h"
21#include "core/hle/service/acc/acc_su.h" 20#include "core/hle/service/acc/acc_su.h"
@@ -25,16 +24,12 @@
25#include "core/hle/service/acc/errors.h" 24#include "core/hle/service/acc/errors.h"
26#include "core/hle/service/acc/profile_manager.h" 25#include "core/hle/service/acc/profile_manager.h"
27#include "core/hle/service/glue/glue_manager.h" 26#include "core/hle/service/glue/glue_manager.h"
27#include "core/hle/service/ipc_helpers.h"
28#include "core/hle/service/server_manager.h"
28#include "core/loader/loader.h" 29#include "core/loader/loader.h"
29 30
30namespace Service::Account { 31namespace Service::Account {
31 32
32constexpr Result ERR_INVALID_USER_ID{ErrorModule::Account, 20};
33constexpr Result ERR_INVALID_APPLICATION_ID{ErrorModule::Account, 22};
34constexpr Result ERR_INVALID_BUFFER{ErrorModule::Account, 30};
35constexpr Result ERR_INVALID_BUFFER_SIZE{ErrorModule::Account, 31};
36constexpr Result ERR_FAILED_SAVE_DATA{ErrorModule::Account, 100};
37
38// Thumbnails are hard coded to be at least this size 33// Thumbnails are hard coded to be at least this size
39constexpr std::size_t THUMBNAIL_SIZE = 0x24000; 34constexpr std::size_t THUMBNAIL_SIZE = 0x24000;
40 35
@@ -294,7 +289,7 @@ public:
294 } 289 }
295 290
296protected: 291protected:
297 void Get(Kernel::HLERequestContext& ctx) { 292 void Get(HLERequestContext& ctx) {
298 LOG_DEBUG(Service_ACC, "called user_id=0x{}", user_id.RawString()); 293 LOG_DEBUG(Service_ACC, "called user_id=0x{}", user_id.RawString());
299 ProfileBase profile_base{}; 294 ProfileBase profile_base{};
300 UserData data{}; 295 UserData data{};
@@ -311,7 +306,7 @@ protected:
311 } 306 }
312 } 307 }
313 308
314 void GetBase(Kernel::HLERequestContext& ctx) { 309 void GetBase(HLERequestContext& ctx) {
315 LOG_DEBUG(Service_ACC, "called user_id=0x{}", user_id.RawString()); 310 LOG_DEBUG(Service_ACC, "called user_id=0x{}", user_id.RawString());
316 ProfileBase profile_base{}; 311 ProfileBase profile_base{};
317 if (profile_manager.GetProfileBase(user_id, profile_base)) { 312 if (profile_manager.GetProfileBase(user_id, profile_base)) {
@@ -325,7 +320,7 @@ protected:
325 } 320 }
326 } 321 }
327 322
328 void LoadImage(Kernel::HLERequestContext& ctx) { 323 void LoadImage(HLERequestContext& ctx) {
329 LOG_DEBUG(Service_ACC, "called"); 324 LOG_DEBUG(Service_ACC, "called");
330 325
331 IPC::ResponseBuilder rb{ctx, 3}; 326 IPC::ResponseBuilder rb{ctx, 3};
@@ -352,7 +347,7 @@ protected:
352 rb.Push<u32>(size); 347 rb.Push<u32>(size);
353 } 348 }
354 349
355 void GetImageSize(Kernel::HLERequestContext& ctx) { 350 void GetImageSize(HLERequestContext& ctx) {
356 LOG_DEBUG(Service_ACC, "called"); 351 LOG_DEBUG(Service_ACC, "called");
357 IPC::ResponseBuilder rb{ctx, 3}; 352 IPC::ResponseBuilder rb{ctx, 3};
358 rb.Push(ResultSuccess); 353 rb.Push(ResultSuccess);
@@ -369,7 +364,7 @@ protected:
369 } 364 }
370 } 365 }
371 366
372 void Store(Kernel::HLERequestContext& ctx) { 367 void Store(HLERequestContext& ctx) {
373 IPC::RequestParser rp{ctx}; 368 IPC::RequestParser rp{ctx};
374 const auto base = rp.PopRaw<ProfileBase>(); 369 const auto base = rp.PopRaw<ProfileBase>();
375 370
@@ -383,7 +378,7 @@ protected:
383 if (user_data.size() < sizeof(UserData)) { 378 if (user_data.size() < sizeof(UserData)) {
384 LOG_ERROR(Service_ACC, "UserData buffer too small!"); 379 LOG_ERROR(Service_ACC, "UserData buffer too small!");
385 IPC::ResponseBuilder rb{ctx, 2}; 380 IPC::ResponseBuilder rb{ctx, 2};
386 rb.Push(ERR_INVALID_BUFFER); 381 rb.Push(Account::ResultInvalidArrayLength);
387 return; 382 return;
388 } 383 }
389 384
@@ -393,7 +388,7 @@ protected:
393 if (!profile_manager.SetProfileBaseAndData(user_id, base, data)) { 388 if (!profile_manager.SetProfileBaseAndData(user_id, base, data)) {
394 LOG_ERROR(Service_ACC, "Failed to update user data and base!"); 389 LOG_ERROR(Service_ACC, "Failed to update user data and base!");
395 IPC::ResponseBuilder rb{ctx, 2}; 390 IPC::ResponseBuilder rb{ctx, 2};
396 rb.Push(ERR_FAILED_SAVE_DATA); 391 rb.Push(Account::ResultAccountUpdateFailed);
397 return; 392 return;
398 } 393 }
399 394
@@ -401,7 +396,7 @@ protected:
401 rb.Push(ResultSuccess); 396 rb.Push(ResultSuccess);
402 } 397 }
403 398
404 void StoreWithImage(Kernel::HLERequestContext& ctx) { 399 void StoreWithImage(HLERequestContext& ctx) {
405 IPC::RequestParser rp{ctx}; 400 IPC::RequestParser rp{ctx};
406 const auto base = rp.PopRaw<ProfileBase>(); 401 const auto base = rp.PopRaw<ProfileBase>();
407 402
@@ -416,7 +411,7 @@ protected:
416 if (user_data.size() < sizeof(UserData)) { 411 if (user_data.size() < sizeof(UserData)) {
417 LOG_ERROR(Service_ACC, "UserData buffer too small!"); 412 LOG_ERROR(Service_ACC, "UserData buffer too small!");
418 IPC::ResponseBuilder rb{ctx, 2}; 413 IPC::ResponseBuilder rb{ctx, 2};
419 rb.Push(ERR_INVALID_BUFFER); 414 rb.Push(Account::ResultInvalidArrayLength);
420 return; 415 return;
421 } 416 }
422 417
@@ -431,7 +426,7 @@ protected:
431 !profile_manager.SetProfileBaseAndData(user_id, base, data)) { 426 !profile_manager.SetProfileBaseAndData(user_id, base, data)) {
432 LOG_ERROR(Service_ACC, "Failed to update profile data, base, and image!"); 427 LOG_ERROR(Service_ACC, "Failed to update profile data, base, and image!");
433 IPC::ResponseBuilder rb{ctx, 2}; 428 IPC::ResponseBuilder rb{ctx, 2};
434 rb.Push(ERR_FAILED_SAVE_DATA); 429 rb.Push(Account::ResultAccountUpdateFailed);
435 return; 430 return;
436 } 431 }
437 432
@@ -498,7 +493,7 @@ public:
498 } 493 }
499 ~EnsureTokenIdCacheAsyncInterface() = default; 494 ~EnsureTokenIdCacheAsyncInterface() = default;
500 495
501 void LoadIdTokenCache(Kernel::HLERequestContext& ctx) { 496 void LoadIdTokenCache(HLERequestContext& ctx) {
502 LOG_WARNING(Service_ACC, "(STUBBED) called"); 497 LOG_WARNING(Service_ACC, "(STUBBED) called");
503 498
504 IPC::ResponseBuilder rb{ctx, 2}; 499 IPC::ResponseBuilder rb{ctx, 2};
@@ -541,14 +536,14 @@ public:
541 } 536 }
542 537
543private: 538private:
544 void CheckAvailability(Kernel::HLERequestContext& ctx) { 539 void CheckAvailability(HLERequestContext& ctx) {
545 LOG_DEBUG(Service_ACC, "(STUBBED) called"); 540 LOG_DEBUG(Service_ACC, "(STUBBED) called");
546 IPC::ResponseBuilder rb{ctx, 3}; 541 IPC::ResponseBuilder rb{ctx, 3};
547 rb.Push(ResultSuccess); 542 rb.Push(ResultSuccess);
548 rb.Push(false); // TODO: Check when this is supposed to return true and when not 543 rb.Push(false); // TODO: Check when this is supposed to return true and when not
549 } 544 }
550 545
551 void GetAccountId(Kernel::HLERequestContext& ctx) { 546 void GetAccountId(HLERequestContext& ctx) {
552 LOG_DEBUG(Service_ACC, "called"); 547 LOG_DEBUG(Service_ACC, "called");
553 548
554 IPC::ResponseBuilder rb{ctx, 4}; 549 IPC::ResponseBuilder rb{ctx, 4};
@@ -556,7 +551,7 @@ private:
556 rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash()); 551 rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash());
557 } 552 }
558 553
559 void EnsureIdTokenCacheAsync(Kernel::HLERequestContext& ctx) { 554 void EnsureIdTokenCacheAsync(HLERequestContext& ctx) {
560 LOG_WARNING(Service_ACC, "(STUBBED) called"); 555 LOG_WARNING(Service_ACC, "(STUBBED) called");
561 556
562 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 557 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -564,13 +559,13 @@ private:
564 rb.PushIpcInterface(ensure_token_id); 559 rb.PushIpcInterface(ensure_token_id);
565 } 560 }
566 561
567 void LoadIdTokenCache(Kernel::HLERequestContext& ctx) { 562 void LoadIdTokenCache(HLERequestContext& ctx) {
568 LOG_WARNING(Service_ACC, "(STUBBED) called"); 563 LOG_WARNING(Service_ACC, "(STUBBED) called");
569 564
570 ensure_token_id->LoadIdTokenCache(ctx); 565 ensure_token_id->LoadIdTokenCache(ctx);
571 } 566 }
572 567
573 void GetNintendoAccountUserResourceCacheForApplication(Kernel::HLERequestContext& ctx) { 568 void GetNintendoAccountUserResourceCacheForApplication(HLERequestContext& ctx) {
574 LOG_WARNING(Service_ACC, "(STUBBED) called"); 569 LOG_WARNING(Service_ACC, "(STUBBED) called");
575 570
576 std::vector<u8> nas_user_base_for_application(0x68); 571 std::vector<u8> nas_user_base_for_application(0x68);
@@ -586,7 +581,7 @@ private:
586 rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash()); 581 rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash());
587 } 582 }
588 583
589 void StoreOpenContext(Kernel::HLERequestContext& ctx) { 584 void StoreOpenContext(HLERequestContext& ctx) {
590 LOG_DEBUG(Service_ACC, "called"); 585 LOG_DEBUG(Service_ACC, "called");
591 586
592 profile_manager->StoreOpenedUsers(); 587 profile_manager->StoreOpenedUsers();
@@ -688,14 +683,14 @@ public:
688 } 683 }
689}; 684};
690 685
691void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) { 686void Module::Interface::GetUserCount(HLERequestContext& ctx) {
692 LOG_DEBUG(Service_ACC, "called"); 687 LOG_DEBUG(Service_ACC, "called");
693 IPC::ResponseBuilder rb{ctx, 3}; 688 IPC::ResponseBuilder rb{ctx, 3};
694 rb.Push(ResultSuccess); 689 rb.Push(ResultSuccess);
695 rb.Push<u32>(static_cast<u32>(profile_manager->GetUserCount())); 690 rb.Push<u32>(static_cast<u32>(profile_manager->GetUserCount()));
696} 691}
697 692
698void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { 693void Module::Interface::GetUserExistence(HLERequestContext& ctx) {
699 IPC::RequestParser rp{ctx}; 694 IPC::RequestParser rp{ctx};
700 Common::UUID user_id = rp.PopRaw<Common::UUID>(); 695 Common::UUID user_id = rp.PopRaw<Common::UUID>();
701 LOG_DEBUG(Service_ACC, "called user_id=0x{}", user_id.RawString()); 696 LOG_DEBUG(Service_ACC, "called user_id=0x{}", user_id.RawString());
@@ -705,28 +700,28 @@ void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) {
705 rb.Push(profile_manager->UserExists(user_id)); 700 rb.Push(profile_manager->UserExists(user_id));
706} 701}
707 702
708void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { 703void Module::Interface::ListAllUsers(HLERequestContext& ctx) {
709 LOG_DEBUG(Service_ACC, "called"); 704 LOG_DEBUG(Service_ACC, "called");
710 ctx.WriteBuffer(profile_manager->GetAllUsers()); 705 ctx.WriteBuffer(profile_manager->GetAllUsers());
711 IPC::ResponseBuilder rb{ctx, 2}; 706 IPC::ResponseBuilder rb{ctx, 2};
712 rb.Push(ResultSuccess); 707 rb.Push(ResultSuccess);
713} 708}
714 709
715void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { 710void Module::Interface::ListOpenUsers(HLERequestContext& ctx) {
716 LOG_DEBUG(Service_ACC, "called"); 711 LOG_DEBUG(Service_ACC, "called");
717 ctx.WriteBuffer(profile_manager->GetOpenUsers()); 712 ctx.WriteBuffer(profile_manager->GetOpenUsers());
718 IPC::ResponseBuilder rb{ctx, 2}; 713 IPC::ResponseBuilder rb{ctx, 2};
719 rb.Push(ResultSuccess); 714 rb.Push(ResultSuccess);
720} 715}
721 716
722void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { 717void Module::Interface::GetLastOpenedUser(HLERequestContext& ctx) {
723 LOG_DEBUG(Service_ACC, "called"); 718 LOG_DEBUG(Service_ACC, "called");
724 IPC::ResponseBuilder rb{ctx, 6}; 719 IPC::ResponseBuilder rb{ctx, 6};
725 rb.Push(ResultSuccess); 720 rb.Push(ResultSuccess);
726 rb.PushRaw<Common::UUID>(profile_manager->GetLastOpenedUser()); 721 rb.PushRaw<Common::UUID>(profile_manager->GetLastOpenedUser());
727} 722}
728 723
729void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { 724void Module::Interface::GetProfile(HLERequestContext& ctx) {
730 IPC::RequestParser rp{ctx}; 725 IPC::RequestParser rp{ctx};
731 Common::UUID user_id = rp.PopRaw<Common::UUID>(); 726 Common::UUID user_id = rp.PopRaw<Common::UUID>();
732 LOG_DEBUG(Service_ACC, "called user_id=0x{}", user_id.RawString()); 727 LOG_DEBUG(Service_ACC, "called user_id=0x{}", user_id.RawString());
@@ -736,20 +731,20 @@ void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) {
736 rb.PushIpcInterface<IProfile>(system, user_id, *profile_manager); 731 rb.PushIpcInterface<IProfile>(system, user_id, *profile_manager);
737} 732}
738 733
739void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx) { 734void Module::Interface::IsUserRegistrationRequestPermitted(HLERequestContext& ctx) {
740 LOG_WARNING(Service_ACC, "(STUBBED) called"); 735 LOG_WARNING(Service_ACC, "(STUBBED) called");
741 IPC::ResponseBuilder rb{ctx, 3}; 736 IPC::ResponseBuilder rb{ctx, 3};
742 rb.Push(ResultSuccess); 737 rb.Push(ResultSuccess);
743 rb.Push(profile_manager->CanSystemRegisterUser()); 738 rb.Push(profile_manager->CanSystemRegisterUser());
744} 739}
745 740
746void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) { 741void Module::Interface::InitializeApplicationInfo(HLERequestContext& ctx) {
747 LOG_DEBUG(Service_ACC, "called"); 742 LOG_DEBUG(Service_ACC, "called");
748 IPC::ResponseBuilder rb{ctx, 2}; 743 IPC::ResponseBuilder rb{ctx, 2};
749 rb.Push(InitializeApplicationInfoBase()); 744 rb.Push(InitializeApplicationInfoBase());
750} 745}
751 746
752void Module::Interface::InitializeApplicationInfoRestricted(Kernel::HLERequestContext& ctx) { 747void Module::Interface::InitializeApplicationInfoRestricted(HLERequestContext& ctx) {
753 LOG_WARNING(Service_ACC, "(Partial implementation) called"); 748 LOG_WARNING(Service_ACC, "(Partial implementation) called");
754 749
755 // TODO(ogniK): We require checking if the user actually owns the title and what not. As of 750 // TODO(ogniK): We require checking if the user actually owns the title and what not. As of
@@ -763,7 +758,7 @@ void Module::Interface::InitializeApplicationInfoRestricted(Kernel::HLERequestCo
763Result Module::Interface::InitializeApplicationInfoBase() { 758Result Module::Interface::InitializeApplicationInfoBase() {
764 if (application_info) { 759 if (application_info) {
765 LOG_ERROR(Service_ACC, "Application already initialized"); 760 LOG_ERROR(Service_ACC, "Application already initialized");
766 return ERR_ACCOUNTINFO_ALREADY_INITIALIZED; 761 return Account::ResultApplicationInfoAlreadyInitialized;
767 } 762 }
768 763
769 // TODO(ogniK): This should be changed to reflect the target process for when we have multiple 764 // TODO(ogniK): This should be changed to reflect the target process for when we have multiple
@@ -774,7 +769,7 @@ Result Module::Interface::InitializeApplicationInfoBase() {
774 769
775 if (launch_property.Failed()) { 770 if (launch_property.Failed()) {
776 LOG_ERROR(Service_ACC, "Failed to get launch property"); 771 LOG_ERROR(Service_ACC, "Failed to get launch property");
777 return ERR_ACCOUNTINFO_BAD_APPLICATION; 772 return Account::ResultInvalidApplication;
778 } 773 }
779 774
780 switch (launch_property->base_game_storage_id) { 775 switch (launch_property->base_game_storage_id) {
@@ -790,7 +785,7 @@ Result Module::Interface::InitializeApplicationInfoBase() {
790 default: 785 default:
791 LOG_ERROR(Service_ACC, "Invalid game storage ID! storage_id={}", 786 LOG_ERROR(Service_ACC, "Invalid game storage ID! storage_id={}",
792 launch_property->base_game_storage_id); 787 launch_property->base_game_storage_id);
793 return ERR_ACCOUNTINFO_BAD_APPLICATION; 788 return Account::ResultInvalidApplication;
794 } 789 }
795 790
796 LOG_WARNING(Service_ACC, "ApplicationInfo init required"); 791 LOG_WARNING(Service_ACC, "ApplicationInfo init required");
@@ -799,14 +794,14 @@ Result Module::Interface::InitializeApplicationInfoBase() {
799 return ResultSuccess; 794 return ResultSuccess;
800} 795}
801 796
802void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx) { 797void Module::Interface::GetBaasAccountManagerForApplication(HLERequestContext& ctx) {
803 LOG_DEBUG(Service_ACC, "called"); 798 LOG_DEBUG(Service_ACC, "called");
804 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 799 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
805 rb.Push(ResultSuccess); 800 rb.Push(ResultSuccess);
806 rb.PushIpcInterface<IManagerForApplication>(system, profile_manager); 801 rb.PushIpcInterface<IManagerForApplication>(system, profile_manager);
807} 802}
808 803
809void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) { 804void Module::Interface::IsUserAccountSwitchLocked(HLERequestContext& ctx) {
810 LOG_DEBUG(Service_ACC, "called"); 805 LOG_DEBUG(Service_ACC, "called");
811 FileSys::NACP nacp; 806 FileSys::NACP nacp;
812 const auto res = system.GetAppLoader().ReadControlData(nacp); 807 const auto res = system.GetAppLoader().ReadControlData(nacp);
@@ -833,14 +828,14 @@ void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx
833 rb.Push(is_locked); 828 rb.Push(is_locked);
834} 829}
835 830
836void Module::Interface::InitializeApplicationInfoV2(Kernel::HLERequestContext& ctx) { 831void Module::Interface::InitializeApplicationInfoV2(HLERequestContext& ctx) {
837 LOG_WARNING(Service_ACC, "(STUBBED) called"); 832 LOG_WARNING(Service_ACC, "(STUBBED) called");
838 833
839 IPC::ResponseBuilder rb{ctx, 2}; 834 IPC::ResponseBuilder rb{ctx, 2};
840 rb.Push(ResultSuccess); 835 rb.Push(ResultSuccess);
841} 836}
842 837
843void Module::Interface::GetProfileEditor(Kernel::HLERequestContext& ctx) { 838void Module::Interface::GetProfileEditor(HLERequestContext& ctx) {
844 IPC::RequestParser rp{ctx}; 839 IPC::RequestParser rp{ctx};
845 Common::UUID user_id = rp.PopRaw<Common::UUID>(); 840 Common::UUID user_id = rp.PopRaw<Common::UUID>();
846 841
@@ -851,7 +846,7 @@ void Module::Interface::GetProfileEditor(Kernel::HLERequestContext& ctx) {
851 rb.PushIpcInterface<IProfileEditor>(system, user_id, *profile_manager); 846 rb.PushIpcInterface<IProfileEditor>(system, user_id, *profile_manager);
852} 847}
853 848
854void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) { 849void Module::Interface::ListQualifiedUsers(HLERequestContext& ctx) {
855 LOG_DEBUG(Service_ACC, "called"); 850 LOG_DEBUG(Service_ACC, "called");
856 851
857 // All users should be qualified. We don't actually have parental control or anything to do with 852 // All users should be qualified. We don't actually have parental control or anything to do with
@@ -862,7 +857,7 @@ void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) {
862 rb.Push(ResultSuccess); 857 rb.Push(ResultSuccess);
863} 858}
864 859
865void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx) { 860void Module::Interface::ListOpenContextStoredUsers(HLERequestContext& ctx) {
866 LOG_DEBUG(Service_ACC, "called"); 861 LOG_DEBUG(Service_ACC, "called");
867 862
868 ctx.WriteBuffer(profile_manager->GetStoredOpenedUsers()); 863 ctx.WriteBuffer(profile_manager->GetStoredOpenedUsers());
@@ -870,7 +865,7 @@ void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ct
870 rb.Push(ResultSuccess); 865 rb.Push(ResultSuccess);
871} 866}
872 867
873void Module::Interface::StoreSaveDataThumbnailApplication(Kernel::HLERequestContext& ctx) { 868void Module::Interface::StoreSaveDataThumbnailApplication(HLERequestContext& ctx) {
874 IPC::RequestParser rp{ctx}; 869 IPC::RequestParser rp{ctx};
875 const auto uuid = rp.PopRaw<Common::UUID>(); 870 const auto uuid = rp.PopRaw<Common::UUID>();
876 871
@@ -883,7 +878,7 @@ void Module::Interface::StoreSaveDataThumbnailApplication(Kernel::HLERequestCont
883 StoreSaveDataThumbnail(ctx, uuid, tid); 878 StoreSaveDataThumbnail(ctx, uuid, tid);
884} 879}
885 880
886void Module::Interface::StoreSaveDataThumbnailSystem(Kernel::HLERequestContext& ctx) { 881void Module::Interface::StoreSaveDataThumbnailSystem(HLERequestContext& ctx) {
887 IPC::RequestParser rp{ctx}; 882 IPC::RequestParser rp{ctx};
888 const auto uuid = rp.PopRaw<Common::UUID>(); 883 const auto uuid = rp.PopRaw<Common::UUID>();
889 const auto tid = rp.Pop<u64_le>(); 884 const auto tid = rp.Pop<u64_le>();
@@ -892,26 +887,26 @@ void Module::Interface::StoreSaveDataThumbnailSystem(Kernel::HLERequestContext&
892 StoreSaveDataThumbnail(ctx, uuid, tid); 887 StoreSaveDataThumbnail(ctx, uuid, tid);
893} 888}
894 889
895void Module::Interface::StoreSaveDataThumbnail(Kernel::HLERequestContext& ctx, 890void Module::Interface::StoreSaveDataThumbnail(HLERequestContext& ctx, const Common::UUID& uuid,
896 const Common::UUID& uuid, const u64 tid) { 891 const u64 tid) {
897 IPC::ResponseBuilder rb{ctx, 2}; 892 IPC::ResponseBuilder rb{ctx, 2};
898 893
899 if (tid == 0) { 894 if (tid == 0) {
900 LOG_ERROR(Service_ACC, "TitleID is not valid!"); 895 LOG_ERROR(Service_ACC, "TitleID is not valid!");
901 rb.Push(ERR_INVALID_APPLICATION_ID); 896 rb.Push(Account::ResultInvalidApplication);
902 return; 897 return;
903 } 898 }
904 899
905 if (uuid.IsInvalid()) { 900 if (uuid.IsInvalid()) {
906 LOG_ERROR(Service_ACC, "User ID is not valid!"); 901 LOG_ERROR(Service_ACC, "User ID is not valid!");
907 rb.Push(ERR_INVALID_USER_ID); 902 rb.Push(Account::ResultInvalidUserId);
908 return; 903 return;
909 } 904 }
910 const auto thumbnail_size = ctx.GetReadBufferSize(); 905 const auto thumbnail_size = ctx.GetReadBufferSize();
911 if (thumbnail_size != THUMBNAIL_SIZE) { 906 if (thumbnail_size != THUMBNAIL_SIZE) {
912 LOG_ERROR(Service_ACC, "Buffer size is empty! size={:X} expecting {:X}", thumbnail_size, 907 LOG_ERROR(Service_ACC, "Buffer size is empty! size={:X} expecting {:X}", thumbnail_size,
913 THUMBNAIL_SIZE); 908 THUMBNAIL_SIZE);
914 rb.Push(ERR_INVALID_BUFFER_SIZE); 909 rb.Push(Account::ResultInvalidArrayLength);
915 return; 910 return;
916 } 911 }
917 912
@@ -919,7 +914,7 @@ void Module::Interface::StoreSaveDataThumbnail(Kernel::HLERequestContext& ctx,
919 rb.Push(ResultSuccess); 914 rb.Push(ResultSuccess);
920} 915}
921 916
922void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx) { 917void Module::Interface::TrySelectUserWithoutInteraction(HLERequestContext& ctx) {
923 LOG_DEBUG(Service_ACC, "called"); 918 LOG_DEBUG(Service_ACC, "called");
924 // A u8 is passed into this function which we can safely ignore. It's to determine if we have 919 // A u8 is passed into this function which we can safely ignore. It's to determine if we have
925 // access to use the network or not by the looks of it 920 // access to use the network or not by the looks of it
@@ -950,18 +945,20 @@ Module::Interface::Interface(std::shared_ptr<Module> module_,
950 945
951Module::Interface::~Interface() = default; 946Module::Interface::~Interface() = default;
952 947
953void InstallInterfaces(Core::System& system) { 948void LoopProcess(Core::System& system) {
954 auto module = std::make_shared<Module>(); 949 auto module = std::make_shared<Module>();
955 auto profile_manager = std::make_shared<ProfileManager>(); 950 auto profile_manager = std::make_shared<ProfileManager>();
956 951 auto server_manager = std::make_unique<ServerManager>(system);
957 std::make_shared<ACC_AA>(module, profile_manager, system) 952
958 ->InstallAsService(system.ServiceManager()); 953 server_manager->RegisterNamedService("acc:aa",
959 std::make_shared<ACC_SU>(module, profile_manager, system) 954 std::make_shared<ACC_AA>(module, profile_manager, system));
960 ->InstallAsService(system.ServiceManager()); 955 server_manager->RegisterNamedService("acc:su",
961 std::make_shared<ACC_U0>(module, profile_manager, system) 956 std::make_shared<ACC_SU>(module, profile_manager, system));
962 ->InstallAsService(system.ServiceManager()); 957 server_manager->RegisterNamedService("acc:u0",
963 std::make_shared<ACC_U1>(module, profile_manager, system) 958 std::make_shared<ACC_U0>(module, profile_manager, system));
964 ->InstallAsService(system.ServiceManager()); 959 server_manager->RegisterNamedService("acc:u1",
960 std::make_shared<ACC_U1>(module, profile_manager, system));
961 ServerManager::RunServer(std::move(server_manager));
965} 962}
966 963
967} // namespace Service::Account 964} // namespace Service::Account
diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h
index 9411b0b92..6b4735c2f 100644
--- a/src/core/hle/service/acc/acc.h
+++ b/src/core/hle/service/acc/acc.h
@@ -20,28 +20,28 @@ public:
20 const char* name); 20 const char* name);
21 ~Interface() override; 21 ~Interface() override;
22 22
23 void GetUserCount(Kernel::HLERequestContext& ctx); 23 void GetUserCount(HLERequestContext& ctx);
24 void GetUserExistence(Kernel::HLERequestContext& ctx); 24 void GetUserExistence(HLERequestContext& ctx);
25 void ListAllUsers(Kernel::HLERequestContext& ctx); 25 void ListAllUsers(HLERequestContext& ctx);
26 void ListOpenUsers(Kernel::HLERequestContext& ctx); 26 void ListOpenUsers(HLERequestContext& ctx);
27 void GetLastOpenedUser(Kernel::HLERequestContext& ctx); 27 void GetLastOpenedUser(HLERequestContext& ctx);
28 void GetProfile(Kernel::HLERequestContext& ctx); 28 void GetProfile(HLERequestContext& ctx);
29 void InitializeApplicationInfo(Kernel::HLERequestContext& ctx); 29 void InitializeApplicationInfo(HLERequestContext& ctx);
30 void InitializeApplicationInfoRestricted(Kernel::HLERequestContext& ctx); 30 void InitializeApplicationInfoRestricted(HLERequestContext& ctx);
31 void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx); 31 void GetBaasAccountManagerForApplication(HLERequestContext& ctx);
32 void IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx); 32 void IsUserRegistrationRequestPermitted(HLERequestContext& ctx);
33 void TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx); 33 void TrySelectUserWithoutInteraction(HLERequestContext& ctx);
34 void IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx); 34 void IsUserAccountSwitchLocked(HLERequestContext& ctx);
35 void InitializeApplicationInfoV2(Kernel::HLERequestContext& ctx); 35 void InitializeApplicationInfoV2(HLERequestContext& ctx);
36 void GetProfileEditor(Kernel::HLERequestContext& ctx); 36 void GetProfileEditor(HLERequestContext& ctx);
37 void ListQualifiedUsers(Kernel::HLERequestContext& ctx); 37 void ListQualifiedUsers(HLERequestContext& ctx);
38 void ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx); 38 void ListOpenContextStoredUsers(HLERequestContext& ctx);
39 void StoreSaveDataThumbnailApplication(Kernel::HLERequestContext& ctx); 39 void StoreSaveDataThumbnailApplication(HLERequestContext& ctx);
40 void StoreSaveDataThumbnailSystem(Kernel::HLERequestContext& ctx); 40 void StoreSaveDataThumbnailSystem(HLERequestContext& ctx);
41 41
42 private: 42 private:
43 Result InitializeApplicationInfoBase(); 43 Result InitializeApplicationInfoBase();
44 void StoreSaveDataThumbnail(Kernel::HLERequestContext& ctx, const Common::UUID& uuid, 44 void StoreSaveDataThumbnail(HLERequestContext& ctx, const Common::UUID& uuid,
45 const u64 tid); 45 const u64 tid);
46 46
47 enum class ApplicationType : u32_le { 47 enum class ApplicationType : u32_le {
@@ -67,7 +67,6 @@ public:
67 }; 67 };
68}; 68};
69 69
70/// Registers all ACC services with the specified service manager. 70void LoopProcess(Core::System& system);
71void InstallInterfaces(Core::System& system);
72 71
73} // namespace Service::Account 72} // namespace Service::Account
diff --git a/src/core/hle/service/acc/async_context.cpp b/src/core/hle/service/acc/async_context.cpp
index 713689d8f..c9e0af90c 100644
--- a/src/core/hle/service/acc/async_context.cpp
+++ b/src/core/hle/service/acc/async_context.cpp
@@ -2,9 +2,9 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/kernel/k_event.h" 5#include "core/hle/kernel/k_event.h"
7#include "core/hle/service/acc/async_context.h" 6#include "core/hle/service/acc/async_context.h"
7#include "core/hle/service/ipc_helpers.h"
8 8
9namespace Service::Account { 9namespace Service::Account {
10IAsyncContext::IAsyncContext(Core::System& system_) 10IAsyncContext::IAsyncContext(Core::System& system_)
@@ -27,7 +27,7 @@ IAsyncContext::~IAsyncContext() {
27 service_context.CloseEvent(completion_event); 27 service_context.CloseEvent(completion_event);
28} 28}
29 29
30void IAsyncContext::GetSystemEvent(Kernel::HLERequestContext& ctx) { 30void IAsyncContext::GetSystemEvent(HLERequestContext& ctx) {
31 LOG_DEBUG(Service_ACC, "called"); 31 LOG_DEBUG(Service_ACC, "called");
32 32
33 IPC::ResponseBuilder rb{ctx, 2, 1}; 33 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -35,7 +35,7 @@ void IAsyncContext::GetSystemEvent(Kernel::HLERequestContext& ctx) {
35 rb.PushCopyObjects(completion_event->GetReadableEvent()); 35 rb.PushCopyObjects(completion_event->GetReadableEvent());
36} 36}
37 37
38void IAsyncContext::Cancel(Kernel::HLERequestContext& ctx) { 38void IAsyncContext::Cancel(HLERequestContext& ctx) {
39 LOG_DEBUG(Service_ACC, "called"); 39 LOG_DEBUG(Service_ACC, "called");
40 40
41 Cancel(); 41 Cancel();
@@ -45,7 +45,7 @@ void IAsyncContext::Cancel(Kernel::HLERequestContext& ctx) {
45 rb.Push(ResultSuccess); 45 rb.Push(ResultSuccess);
46} 46}
47 47
48void IAsyncContext::HasDone(Kernel::HLERequestContext& ctx) { 48void IAsyncContext::HasDone(HLERequestContext& ctx) {
49 LOG_DEBUG(Service_ACC, "called"); 49 LOG_DEBUG(Service_ACC, "called");
50 50
51 is_complete.store(IsComplete()); 51 is_complete.store(IsComplete());
@@ -55,7 +55,7 @@ void IAsyncContext::HasDone(Kernel::HLERequestContext& ctx) {
55 rb.Push(is_complete.load()); 55 rb.Push(is_complete.load());
56} 56}
57 57
58void IAsyncContext::GetResult(Kernel::HLERequestContext& ctx) { 58void IAsyncContext::GetResult(HLERequestContext& ctx) {
59 LOG_DEBUG(Service_ACC, "called"); 59 LOG_DEBUG(Service_ACC, "called");
60 60
61 IPC::ResponseBuilder rb{ctx, 3}; 61 IPC::ResponseBuilder rb{ctx, 3};
diff --git a/src/core/hle/service/acc/async_context.h b/src/core/hle/service/acc/async_context.h
index 26332d241..d7bffc055 100644
--- a/src/core/hle/service/acc/async_context.h
+++ b/src/core/hle/service/acc/async_context.h
@@ -18,10 +18,10 @@ public:
18 explicit IAsyncContext(Core::System& system_); 18 explicit IAsyncContext(Core::System& system_);
19 ~IAsyncContext() override; 19 ~IAsyncContext() override;
20 20
21 void GetSystemEvent(Kernel::HLERequestContext& ctx); 21 void GetSystemEvent(HLERequestContext& ctx);
22 void Cancel(Kernel::HLERequestContext& ctx); 22 void Cancel(HLERequestContext& ctx);
23 void HasDone(Kernel::HLERequestContext& ctx); 23 void HasDone(HLERequestContext& ctx);
24 void GetResult(Kernel::HLERequestContext& ctx); 24 void GetResult(HLERequestContext& ctx);
25 25
26protected: 26protected:
27 virtual bool IsComplete() const = 0; 27 virtual bool IsComplete() const = 0;
diff --git a/src/core/hle/service/acc/errors.h b/src/core/hle/service/acc/errors.h
index e9c16b951..433ebfe9d 100644
--- a/src/core/hle/service/acc/errors.h
+++ b/src/core/hle/service/acc/errors.h
@@ -7,7 +7,13 @@
7 7
8namespace Service::Account { 8namespace Service::Account {
9 9
10constexpr Result ERR_ACCOUNTINFO_BAD_APPLICATION{ErrorModule::Account, 22}; 10constexpr Result ResultCancelledByUser{ErrorModule::Account, 1};
11constexpr Result ERR_ACCOUNTINFO_ALREADY_INITIALIZED{ErrorModule::Account, 41}; 11constexpr Result ResultNoNotifications{ErrorModule::Account, 15};
12constexpr Result ResultInvalidUserId{ErrorModule::Account, 20};
13constexpr Result ResultInvalidApplication{ErrorModule::Account, 22};
14constexpr Result ResultNullptr{ErrorModule::Account, 30};
15constexpr Result ResultInvalidArrayLength{ErrorModule::Account, 32};
16constexpr Result ResultApplicationInfoAlreadyInitialized{ErrorModule::Account, 41};
17constexpr Result ResultAccountUpdateFailed{ErrorModule::Account, 100};
12 18
13} // namespace Service::Account 19} // namespace Service::Account
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 26af499d2..f17df5124 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -11,7 +11,6 @@
11#include "core/file_sys/patch_manager.h" 11#include "core/file_sys/patch_manager.h"
12#include "core/file_sys/registered_cache.h" 12#include "core/file_sys/registered_cache.h"
13#include "core/file_sys/savedata_factory.h" 13#include "core/file_sys/savedata_factory.h"
14#include "core/hle/ipc_helpers.h"
15#include "core/hle/kernel/k_event.h" 14#include "core/hle/kernel/k_event.h"
16#include "core/hle/kernel/k_transfer_memory.h" 15#include "core/hle/kernel/k_transfer_memory.h"
17#include "core/hle/service/acc/profile_manager.h" 16#include "core/hle/service/acc/profile_manager.h"
@@ -29,18 +28,20 @@
29#include "core/hle/service/bcat/backend/backend.h" 28#include "core/hle/service/bcat/backend/backend.h"
30#include "core/hle/service/caps/caps.h" 29#include "core/hle/service/caps/caps.h"
31#include "core/hle/service/filesystem/filesystem.h" 30#include "core/hle/service/filesystem/filesystem.h"
31#include "core/hle/service/ipc_helpers.h"
32#include "core/hle/service/ns/ns.h" 32#include "core/hle/service/ns/ns.h"
33#include "core/hle/service/nvflinger/nvflinger.h" 33#include "core/hle/service/nvnflinger/nvnflinger.h"
34#include "core/hle/service/pm/pm.h" 34#include "core/hle/service/pm/pm.h"
35#include "core/hle/service/server_manager.h"
35#include "core/hle/service/sm/sm.h" 36#include "core/hle/service/sm/sm.h"
36#include "core/hle/service/vi/vi.h" 37#include "core/hle/service/vi/vi.h"
37#include "core/memory.h" 38#include "core/memory.h"
38 39
39namespace Service::AM { 40namespace Service::AM {
40 41
41constexpr Result ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 2}; 42constexpr Result ResultNoDataInChannel{ErrorModule::AM, 2};
42constexpr Result ERR_NO_MESSAGES{ErrorModule::AM, 3}; 43constexpr Result ResultNoMessages{ErrorModule::AM, 3};
43constexpr Result ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 503}; 44constexpr Result ResultInvalidOffset{ErrorModule::AM, 503};
44 45
45enum class LaunchParameterKind : u32 { 46enum class LaunchParameterKind : u32 {
46 ApplicationSpecific = 1, 47 ApplicationSpecific = 1,
@@ -77,7 +78,7 @@ IWindowController::IWindowController(Core::System& system_)
77 78
78IWindowController::~IWindowController() = default; 79IWindowController::~IWindowController() = default;
79 80
80void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) { 81void IWindowController::GetAppletResourceUserId(HLERequestContext& ctx) {
81 const u64 process_id = system.ApplicationProcess()->GetProcessID(); 82 const u64 process_id = system.ApplicationProcess()->GetProcessID();
82 83
83 LOG_DEBUG(Service_AM, "called. Process ID=0x{:016X}", process_id); 84 LOG_DEBUG(Service_AM, "called. Process ID=0x{:016X}", process_id);
@@ -87,7 +88,7 @@ void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx)
87 rb.Push<u64>(process_id); 88 rb.Push<u64>(process_id);
88} 89}
89 90
90void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) { 91void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) {
91 LOG_WARNING(Service_AM, "(STUBBED) called"); 92 LOG_WARNING(Service_AM, "(STUBBED) called");
92 IPC::ResponseBuilder rb{ctx, 2}; 93 IPC::ResponseBuilder rb{ctx, 2};
93 rb.Push(ResultSuccess); 94 rb.Push(ResultSuccess);
@@ -110,7 +111,7 @@ IAudioController::IAudioController(Core::System& system_)
110 111
111IAudioController::~IAudioController() = default; 112IAudioController::~IAudioController() = default;
112 113
113void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) { 114void IAudioController::SetExpectedMasterVolume(HLERequestContext& ctx) {
114 IPC::RequestParser rp{ctx}; 115 IPC::RequestParser rp{ctx};
115 const float main_applet_volume_tmp = rp.Pop<float>(); 116 const float main_applet_volume_tmp = rp.Pop<float>();
116 const float library_applet_volume_tmp = rp.Pop<float>(); 117 const float library_applet_volume_tmp = rp.Pop<float>();
@@ -127,21 +128,21 @@ void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
127 rb.Push(ResultSuccess); 128 rb.Push(ResultSuccess);
128} 129}
129 130
130void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { 131void IAudioController::GetMainAppletExpectedMasterVolume(HLERequestContext& ctx) {
131 LOG_DEBUG(Service_AM, "called. main_applet_volume={}", main_applet_volume); 132 LOG_DEBUG(Service_AM, "called. main_applet_volume={}", main_applet_volume);
132 IPC::ResponseBuilder rb{ctx, 3}; 133 IPC::ResponseBuilder rb{ctx, 3};
133 rb.Push(ResultSuccess); 134 rb.Push(ResultSuccess);
134 rb.Push(main_applet_volume); 135 rb.Push(main_applet_volume);
135} 136}
136 137
137void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { 138void IAudioController::GetLibraryAppletExpectedMasterVolume(HLERequestContext& ctx) {
138 LOG_DEBUG(Service_AM, "called. library_applet_volume={}", library_applet_volume); 139 LOG_DEBUG(Service_AM, "called. library_applet_volume={}", library_applet_volume);
139 IPC::ResponseBuilder rb{ctx, 3}; 140 IPC::ResponseBuilder rb{ctx, 3};
140 rb.Push(ResultSuccess); 141 rb.Push(ResultSuccess);
141 rb.Push(library_applet_volume); 142 rb.Push(library_applet_volume);
142} 143}
143 144
144void IAudioController::ChangeMainAppletMasterVolume(Kernel::HLERequestContext& ctx) { 145void IAudioController::ChangeMainAppletMasterVolume(HLERequestContext& ctx) {
145 struct Parameters { 146 struct Parameters {
146 float volume; 147 float volume;
147 s64 fade_time_ns; 148 s64 fade_time_ns;
@@ -161,7 +162,7 @@ void IAudioController::ChangeMainAppletMasterVolume(Kernel::HLERequestContext& c
161 rb.Push(ResultSuccess); 162 rb.Push(ResultSuccess);
162} 163}
163 164
164void IAudioController::SetTransparentAudioRate(Kernel::HLERequestContext& ctx) { 165void IAudioController::SetTransparentAudioRate(HLERequestContext& ctx) {
165 IPC::RequestParser rp{ctx}; 166 IPC::RequestParser rp{ctx};
166 const float transparent_volume_rate_tmp = rp.Pop<float>(); 167 const float transparent_volume_rate_tmp = rp.Pop<float>();
167 168
@@ -250,10 +251,9 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
250 251
251IDebugFunctions::~IDebugFunctions() = default; 252IDebugFunctions::~IDebugFunctions() = default;
252 253
253ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_) 254ISelfController::ISelfController(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger_)
254 : ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_}, service_context{ 255 : ServiceFramework{system_, "ISelfController"}, nvnflinger{nvnflinger_},
255 system, 256 service_context{system, "ISelfController"} {
256 "ISelfController"} {
257 // clang-format off 257 // clang-format off
258 static const FunctionInfo functions[] = { 258 static const FunctionInfo functions[] = {
259 {0, &ISelfController::Exit, "Exit"}, 259 {0, &ISelfController::Exit, "Exit"},
@@ -327,7 +327,7 @@ ISelfController::~ISelfController() {
327 service_context.CloseEvent(accumulated_suspended_tick_changed_event); 327 service_context.CloseEvent(accumulated_suspended_tick_changed_event);
328} 328}
329 329
330void ISelfController::Exit(Kernel::HLERequestContext& ctx) { 330void ISelfController::Exit(HLERequestContext& ctx) {
331 LOG_DEBUG(Service_AM, "called"); 331 LOG_DEBUG(Service_AM, "called");
332 332
333 IPC::ResponseBuilder rb{ctx, 2}; 333 IPC::ResponseBuilder rb{ctx, 2};
@@ -336,7 +336,7 @@ void ISelfController::Exit(Kernel::HLERequestContext& ctx) {
336 system.Exit(); 336 system.Exit();
337} 337}
338 338
339void ISelfController::LockExit(Kernel::HLERequestContext& ctx) { 339void ISelfController::LockExit(HLERequestContext& ctx) {
340 LOG_DEBUG(Service_AM, "called"); 340 LOG_DEBUG(Service_AM, "called");
341 341
342 system.SetExitLock(true); 342 system.SetExitLock(true);
@@ -345,7 +345,7 @@ void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
345 rb.Push(ResultSuccess); 345 rb.Push(ResultSuccess);
346} 346}
347 347
348void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) { 348void ISelfController::UnlockExit(HLERequestContext& ctx) {
349 LOG_DEBUG(Service_AM, "called"); 349 LOG_DEBUG(Service_AM, "called");
350 350
351 system.SetExitLock(false); 351 system.SetExitLock(false);
@@ -354,7 +354,7 @@ void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
354 rb.Push(ResultSuccess); 354 rb.Push(ResultSuccess);
355} 355}
356 356
357void ISelfController::EnterFatalSection(Kernel::HLERequestContext& ctx) { 357void ISelfController::EnterFatalSection(HLERequestContext& ctx) {
358 ++num_fatal_sections_entered; 358 ++num_fatal_sections_entered;
359 LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", num_fatal_sections_entered); 359 LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", num_fatal_sections_entered);
360 360
@@ -362,7 +362,7 @@ void ISelfController::EnterFatalSection(Kernel::HLERequestContext& ctx) {
362 rb.Push(ResultSuccess); 362 rb.Push(ResultSuccess);
363} 363}
364 364
365void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) { 365void ISelfController::LeaveFatalSection(HLERequestContext& ctx) {
366 LOG_DEBUG(Service_AM, "called."); 366 LOG_DEBUG(Service_AM, "called.");
367 367
368 // Entry and exit of fatal sections must be balanced. 368 // Entry and exit of fatal sections must be balanced.
@@ -378,7 +378,7 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) {
378 rb.Push(ResultSuccess); 378 rb.Push(ResultSuccess);
379} 379}
380 380
381void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { 381void ISelfController::GetLibraryAppletLaunchableEvent(HLERequestContext& ctx) {
382 LOG_WARNING(Service_AM, "(STUBBED) called"); 382 LOG_WARNING(Service_AM, "(STUBBED) called");
383 383
384 launchable_event->Signal(); 384 launchable_event->Signal();
@@ -388,7 +388,7 @@ void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext&
388 rb.PushCopyObjects(launchable_event->GetReadableEvent()); 388 rb.PushCopyObjects(launchable_event->GetReadableEvent());
389} 389}
390 390
391void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { 391void ISelfController::SetScreenShotPermission(HLERequestContext& ctx) {
392 IPC::RequestParser rp{ctx}; 392 IPC::RequestParser rp{ctx};
393 const auto permission = rp.PopEnum<ScreenshotPermission>(); 393 const auto permission = rp.PopEnum<ScreenshotPermission>();
394 LOG_DEBUG(Service_AM, "called, permission={}", permission); 394 LOG_DEBUG(Service_AM, "called, permission={}", permission);
@@ -399,7 +399,7 @@ void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
399 rb.Push(ResultSuccess); 399 rb.Push(ResultSuccess);
400} 400}
401 401
402void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) { 402void ISelfController::SetOperationModeChangedNotification(HLERequestContext& ctx) {
403 IPC::RequestParser rp{ctx}; 403 IPC::RequestParser rp{ctx};
404 404
405 bool flag = rp.Pop<bool>(); 405 bool flag = rp.Pop<bool>();
@@ -409,7 +409,7 @@ void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestCont
409 rb.Push(ResultSuccess); 409 rb.Push(ResultSuccess);
410} 410}
411 411
412void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) { 412void ISelfController::SetPerformanceModeChangedNotification(HLERequestContext& ctx) {
413 IPC::RequestParser rp{ctx}; 413 IPC::RequestParser rp{ctx};
414 414
415 bool flag = rp.Pop<bool>(); 415 bool flag = rp.Pop<bool>();
@@ -419,7 +419,7 @@ void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestCo
419 rb.Push(ResultSuccess); 419 rb.Push(ResultSuccess);
420} 420}
421 421
422void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) { 422void ISelfController::SetFocusHandlingMode(HLERequestContext& ctx) {
423 // Takes 3 input u8s with each field located immediately after the previous 423 // Takes 3 input u8s with each field located immediately after the previous
424 // u8, these are bool flags. No output. 424 // u8, these are bool flags. No output.
425 IPC::RequestParser rp{ctx}; 425 IPC::RequestParser rp{ctx};
@@ -438,14 +438,14 @@ void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
438 rb.Push(ResultSuccess); 438 rb.Push(ResultSuccess);
439} 439}
440 440
441void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) { 441void ISelfController::SetRestartMessageEnabled(HLERequestContext& ctx) {
442 LOG_WARNING(Service_AM, "(STUBBED) called"); 442 LOG_WARNING(Service_AM, "(STUBBED) called");
443 443
444 IPC::ResponseBuilder rb{ctx, 2}; 444 IPC::ResponseBuilder rb{ctx, 2};
445 rb.Push(ResultSuccess); 445 rb.Push(ResultSuccess);
446} 446}
447 447
448void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) { 448void ISelfController::SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx) {
449 // Takes 3 input u8s with each field located immediately after the previous 449 // Takes 3 input u8s with each field located immediately after the previous
450 // u8, these are bool flags. No output. 450 // u8, these are bool flags. No output.
451 IPC::RequestParser rp{ctx}; 451 IPC::RequestParser rp{ctx};
@@ -457,27 +457,27 @@ void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext&
457 rb.Push(ResultSuccess); 457 rb.Push(ResultSuccess);
458} 458}
459 459
460void ISelfController::SetAlbumImageOrientation(Kernel::HLERequestContext& ctx) { 460void ISelfController::SetAlbumImageOrientation(HLERequestContext& ctx) {
461 LOG_WARNING(Service_AM, "(STUBBED) called"); 461 LOG_WARNING(Service_AM, "(STUBBED) called");
462 462
463 IPC::ResponseBuilder rb{ctx, 2}; 463 IPC::ResponseBuilder rb{ctx, 2};
464 rb.Push(ResultSuccess); 464 rb.Push(ResultSuccess);
465} 465}
466 466
467void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) { 467void ISelfController::CreateManagedDisplayLayer(HLERequestContext& ctx) {
468 LOG_WARNING(Service_AM, "(STUBBED) called"); 468 LOG_WARNING(Service_AM, "(STUBBED) called");
469 469
470 // TODO(Subv): Find out how AM determines the display to use, for now just 470 // TODO(Subv): Find out how AM determines the display to use, for now just
471 // create the layer in the Default display. 471 // create the layer in the Default display.
472 const auto display_id = nvflinger.OpenDisplay("Default"); 472 const auto display_id = nvnflinger.OpenDisplay("Default");
473 const auto layer_id = nvflinger.CreateLayer(*display_id); 473 const auto layer_id = nvnflinger.CreateLayer(*display_id);
474 474
475 IPC::ResponseBuilder rb{ctx, 4}; 475 IPC::ResponseBuilder rb{ctx, 4};
476 rb.Push(ResultSuccess); 476 rb.Push(ResultSuccess);
477 rb.Push(*layer_id); 477 rb.Push(*layer_id);
478} 478}
479 479
480void ISelfController::CreateManagedDisplaySeparableLayer(Kernel::HLERequestContext& ctx) { 480void ISelfController::CreateManagedDisplaySeparableLayer(HLERequestContext& ctx) {
481 LOG_WARNING(Service_AM, "(STUBBED) called"); 481 LOG_WARNING(Service_AM, "(STUBBED) called");
482 482
483 // TODO(Subv): Find out how AM determines the display to use, for now just 483 // TODO(Subv): Find out how AM determines the display to use, for now just
@@ -487,22 +487,22 @@ void ISelfController::CreateManagedDisplaySeparableLayer(Kernel::HLERequestConte
487 // Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse 487 // Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse
488 // side effects. 488 // side effects.
489 // TODO: Support multiple layers 489 // TODO: Support multiple layers
490 const auto display_id = nvflinger.OpenDisplay("Default"); 490 const auto display_id = nvnflinger.OpenDisplay("Default");
491 const auto layer_id = nvflinger.CreateLayer(*display_id); 491 const auto layer_id = nvnflinger.CreateLayer(*display_id);
492 492
493 IPC::ResponseBuilder rb{ctx, 4}; 493 IPC::ResponseBuilder rb{ctx, 4};
494 rb.Push(ResultSuccess); 494 rb.Push(ResultSuccess);
495 rb.Push(*layer_id); 495 rb.Push(*layer_id);
496} 496}
497 497
498void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) { 498void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) {
499 LOG_WARNING(Service_AM, "(STUBBED) called"); 499 LOG_WARNING(Service_AM, "(STUBBED) called");
500 500
501 IPC::ResponseBuilder rb{ctx, 2}; 501 IPC::ResponseBuilder rb{ctx, 2};
502 rb.Push(ResultSuccess); 502 rb.Push(ResultSuccess);
503} 503}
504 504
505void ISelfController::SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx) { 505void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) {
506 IPC::RequestParser rp{ctx}; 506 IPC::RequestParser rp{ctx};
507 idle_time_detection_extension = rp.Pop<u32>(); 507 idle_time_detection_extension = rp.Pop<u32>();
508 LOG_WARNING(Service_AM, "(STUBBED) called idle_time_detection_extension={}", 508 LOG_WARNING(Service_AM, "(STUBBED) called idle_time_detection_extension={}",
@@ -512,7 +512,7 @@ void ISelfController::SetIdleTimeDetectionExtension(Kernel::HLERequestContext& c
512 rb.Push(ResultSuccess); 512 rb.Push(ResultSuccess);
513} 513}
514 514
515void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx) { 515void ISelfController::GetIdleTimeDetectionExtension(HLERequestContext& ctx) {
516 LOG_WARNING(Service_AM, "(STUBBED) called"); 516 LOG_WARNING(Service_AM, "(STUBBED) called");
517 517
518 IPC::ResponseBuilder rb{ctx, 3}; 518 IPC::ResponseBuilder rb{ctx, 3};
@@ -520,14 +520,14 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c
520 rb.Push<u32>(idle_time_detection_extension); 520 rb.Push<u32>(idle_time_detection_extension);
521} 521}
522 522
523void ISelfController::ReportUserIsActive(Kernel::HLERequestContext& ctx) { 523void ISelfController::ReportUserIsActive(HLERequestContext& ctx) {
524 LOG_WARNING(Service_AM, "(STUBBED) called"); 524 LOG_WARNING(Service_AM, "(STUBBED) called");
525 525
526 IPC::ResponseBuilder rb{ctx, 2}; 526 IPC::ResponseBuilder rb{ctx, 2};
527 rb.Push(ResultSuccess); 527 rb.Push(ResultSuccess);
528} 528}
529 529
530void ISelfController::SetAutoSleepDisabled(Kernel::HLERequestContext& ctx) { 530void ISelfController::SetAutoSleepDisabled(HLERequestContext& ctx) {
531 IPC::RequestParser rp{ctx}; 531 IPC::RequestParser rp{ctx};
532 is_auto_sleep_disabled = rp.Pop<bool>(); 532 is_auto_sleep_disabled = rp.Pop<bool>();
533 533
@@ -547,7 +547,7 @@ void ISelfController::SetAutoSleepDisabled(Kernel::HLERequestContext& ctx) {
547 rb.Push(ResultSuccess); 547 rb.Push(ResultSuccess);
548} 548}
549 549
550void ISelfController::IsAutoSleepDisabled(Kernel::HLERequestContext& ctx) { 550void ISelfController::IsAutoSleepDisabled(HLERequestContext& ctx) {
551 LOG_DEBUG(Service_AM, "called."); 551 LOG_DEBUG(Service_AM, "called.");
552 552
553 IPC::ResponseBuilder rb{ctx, 3}; 553 IPC::ResponseBuilder rb{ctx, 3};
@@ -555,7 +555,7 @@ void ISelfController::IsAutoSleepDisabled(Kernel::HLERequestContext& ctx) {
555 rb.Push(is_auto_sleep_disabled); 555 rb.Push(is_auto_sleep_disabled);
556} 556}
557 557
558void ISelfController::GetAccumulatedSuspendedTickValue(Kernel::HLERequestContext& ctx) { 558void ISelfController::GetAccumulatedSuspendedTickValue(HLERequestContext& ctx) {
559 LOG_DEBUG(Service_AM, "called."); 559 LOG_DEBUG(Service_AM, "called.");
560 560
561 // This command returns the total number of system ticks since ISelfController creation 561 // This command returns the total number of system ticks since ISelfController creation
@@ -566,7 +566,7 @@ void ISelfController::GetAccumulatedSuspendedTickValue(Kernel::HLERequestContext
566 rb.Push<u64>(0); 566 rb.Push<u64>(0);
567} 567}
568 568
569void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx) { 569void ISelfController::GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx) {
570 LOG_DEBUG(Service_AM, "called."); 570 LOG_DEBUG(Service_AM, "called.");
571 571
572 IPC::ResponseBuilder rb{ctx, 2, 1}; 572 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -574,7 +574,7 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest
574 rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent()); 574 rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent());
575} 575}
576 576
577void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx) { 577void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx) {
578 IPC::RequestParser rp{ctx}; 578 IPC::RequestParser rp{ctx};
579 579
580 // This service call sets an internal flag whether a notification is shown when an image is 580 // This service call sets an internal flag whether a notification is shown when an image is
@@ -589,7 +589,7 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestCo
589 rb.Push(ResultSuccess); 589 rb.Push(ResultSuccess);
590} 590}
591 591
592void ISelfController::SaveCurrentScreenshot(Kernel::HLERequestContext& ctx) { 592void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) {
593 IPC::RequestParser rp{ctx}; 593 IPC::RequestParser rp{ctx};
594 594
595 const auto album_report_option = rp.PopEnum<Capture::AlbumReportOption>(); 595 const auto album_report_option = rp.PopEnum<Capture::AlbumReportOption>();
@@ -600,7 +600,7 @@ void ISelfController::SaveCurrentScreenshot(Kernel::HLERequestContext& ctx) {
600 rb.Push(ResultSuccess); 600 rb.Push(ResultSuccess);
601} 601}
602 602
603void ISelfController::SetRecordVolumeMuted(Kernel::HLERequestContext& ctx) { 603void ISelfController::SetRecordVolumeMuted(HLERequestContext& ctx) {
604 IPC::RequestParser rp{ctx}; 604 IPC::RequestParser rp{ctx};
605 605
606 const auto is_record_volume_muted = rp.Pop<bool>(); 606 const auto is_record_volume_muted = rp.Pop<bool>();
@@ -734,7 +734,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
734 734
735ICommonStateGetter::~ICommonStateGetter() = default; 735ICommonStateGetter::~ICommonStateGetter() = default;
736 736
737void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) { 737void ICommonStateGetter::GetBootMode(HLERequestContext& ctx) {
738 LOG_DEBUG(Service_AM, "called"); 738 LOG_DEBUG(Service_AM, "called");
739 739
740 IPC::ResponseBuilder rb{ctx, 3}; 740 IPC::ResponseBuilder rb{ctx, 3};
@@ -742,7 +742,7 @@ void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) {
742 rb.Push<u8>(static_cast<u8>(Service::PM::SystemBootMode::Normal)); // Normal boot mode 742 rb.Push<u8>(static_cast<u8>(Service::PM::SystemBootMode::Normal)); // Normal boot mode
743} 743}
744 744
745void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) { 745void ICommonStateGetter::GetEventHandle(HLERequestContext& ctx) {
746 LOG_DEBUG(Service_AM, "called"); 746 LOG_DEBUG(Service_AM, "called");
747 747
748 IPC::ResponseBuilder rb{ctx, 2, 1}; 748 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -750,7 +750,7 @@ void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
750 rb.PushCopyObjects(msg_queue->GetMessageReceiveEvent()); 750 rb.PushCopyObjects(msg_queue->GetMessageReceiveEvent());
751} 751}
752 752
753void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) { 753void ICommonStateGetter::ReceiveMessage(HLERequestContext& ctx) {
754 LOG_DEBUG(Service_AM, "called"); 754 LOG_DEBUG(Service_AM, "called");
755 755
756 const auto message = msg_queue->PopMessage(); 756 const auto message = msg_queue->PopMessage();
@@ -758,7 +758,7 @@ void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
758 758
759 if (message == AppletMessageQueue::AppletMessage::None) { 759 if (message == AppletMessageQueue::AppletMessage::None) {
760 LOG_ERROR(Service_AM, "Message queue is empty"); 760 LOG_ERROR(Service_AM, "Message queue is empty");
761 rb.Push(ERR_NO_MESSAGES); 761 rb.Push(AM::ResultNoMessages);
762 rb.PushEnum<AppletMessageQueue::AppletMessage>(message); 762 rb.PushEnum<AppletMessageQueue::AppletMessage>(message);
763 return; 763 return;
764 } 764 }
@@ -767,7 +767,7 @@ void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
767 rb.PushEnum<AppletMessageQueue::AppletMessage>(message); 767 rb.PushEnum<AppletMessageQueue::AppletMessage>(message);
768} 768}
769 769
770void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { 770void ICommonStateGetter::GetCurrentFocusState(HLERequestContext& ctx) {
771 LOG_DEBUG(Service_AM, "(STUBBED) called"); 771 LOG_DEBUG(Service_AM, "(STUBBED) called");
772 772
773 IPC::ResponseBuilder rb{ctx, 3}; 773 IPC::ResponseBuilder rb{ctx, 3};
@@ -775,7 +775,7 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
775 rb.Push(static_cast<u8>(FocusState::InFocus)); 775 rb.Push(static_cast<u8>(FocusState::InFocus));
776} 776}
777 777
778void ICommonStateGetter::IsVrModeEnabled(Kernel::HLERequestContext& ctx) { 778void ICommonStateGetter::IsVrModeEnabled(HLERequestContext& ctx) {
779 LOG_DEBUG(Service_AM, "called"); 779 LOG_DEBUG(Service_AM, "called");
780 780
781 IPC::ResponseBuilder rb{ctx, 3}; 781 IPC::ResponseBuilder rb{ctx, 3};
@@ -783,7 +783,7 @@ void ICommonStateGetter::IsVrModeEnabled(Kernel::HLERequestContext& ctx) {
783 rb.Push(vr_mode_state); 783 rb.Push(vr_mode_state);
784} 784}
785 785
786void ICommonStateGetter::SetVrModeEnabled(Kernel::HLERequestContext& ctx) { 786void ICommonStateGetter::SetVrModeEnabled(HLERequestContext& ctx) {
787 IPC::RequestParser rp{ctx}; 787 IPC::RequestParser rp{ctx};
788 vr_mode_state = rp.Pop<bool>(); 788 vr_mode_state = rp.Pop<bool>();
789 789
@@ -793,7 +793,7 @@ void ICommonStateGetter::SetVrModeEnabled(Kernel::HLERequestContext& ctx) {
793 rb.Push(ResultSuccess); 793 rb.Push(ResultSuccess);
794} 794}
795 795
796void ICommonStateGetter::SetLcdBacklighOffEnabled(Kernel::HLERequestContext& ctx) { 796void ICommonStateGetter::SetLcdBacklighOffEnabled(HLERequestContext& ctx) {
797 IPC::RequestParser rp{ctx}; 797 IPC::RequestParser rp{ctx};
798 const auto is_lcd_backlight_off_enabled = rp.Pop<bool>(); 798 const auto is_lcd_backlight_off_enabled = rp.Pop<bool>();
799 799
@@ -804,21 +804,21 @@ void ICommonStateGetter::SetLcdBacklighOffEnabled(Kernel::HLERequestContext& ctx
804 rb.Push(ResultSuccess); 804 rb.Push(ResultSuccess);
805} 805}
806 806
807void ICommonStateGetter::BeginVrModeEx(Kernel::HLERequestContext& ctx) { 807void ICommonStateGetter::BeginVrModeEx(HLERequestContext& ctx) {
808 LOG_WARNING(Service_AM, "(STUBBED) called"); 808 LOG_WARNING(Service_AM, "(STUBBED) called");
809 809
810 IPC::ResponseBuilder rb{ctx, 2}; 810 IPC::ResponseBuilder rb{ctx, 2};
811 rb.Push(ResultSuccess); 811 rb.Push(ResultSuccess);
812} 812}
813 813
814void ICommonStateGetter::EndVrModeEx(Kernel::HLERequestContext& ctx) { 814void ICommonStateGetter::EndVrModeEx(HLERequestContext& ctx) {
815 LOG_WARNING(Service_AM, "(STUBBED) called"); 815 LOG_WARNING(Service_AM, "(STUBBED) called");
816 816
817 IPC::ResponseBuilder rb{ctx, 2}; 817 IPC::ResponseBuilder rb{ctx, 2};
818 rb.Push(ResultSuccess); 818 rb.Push(ResultSuccess);
819} 819}
820 820
821void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) { 821void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(HLERequestContext& ctx) {
822 LOG_DEBUG(Service_AM, "called"); 822 LOG_DEBUG(Service_AM, "called");
823 823
824 IPC::ResponseBuilder rb{ctx, 2, 1}; 824 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -826,7 +826,7 @@ void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLEReque
826 rb.PushCopyObjects(msg_queue->GetOperationModeChangedEvent()); 826 rb.PushCopyObjects(msg_queue->GetOperationModeChangedEvent());
827} 827}
828 828
829void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx) { 829void ICommonStateGetter::GetDefaultDisplayResolution(HLERequestContext& ctx) {
830 LOG_DEBUG(Service_AM, "called"); 830 LOG_DEBUG(Service_AM, "called");
831 831
832 IPC::ResponseBuilder rb{ctx, 4}; 832 IPC::ResponseBuilder rb{ctx, 4};
@@ -841,7 +841,7 @@ void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext&
841 } 841 }
842} 842}
843 843
844void ICommonStateGetter::SetCpuBoostMode(Kernel::HLERequestContext& ctx) { 844void ICommonStateGetter::SetCpuBoostMode(HLERequestContext& ctx) {
845 LOG_DEBUG(Service_AM, "called, forwarding to APM:SYS"); 845 LOG_DEBUG(Service_AM, "called, forwarding to APM:SYS");
846 846
847 const auto& sm = system.ServiceManager(); 847 const auto& sm = system.ServiceManager();
@@ -851,7 +851,7 @@ void ICommonStateGetter::SetCpuBoostMode(Kernel::HLERequestContext& ctx) {
851 apm_sys->SetCpuBoostMode(ctx); 851 apm_sys->SetCpuBoostMode(ctx);
852} 852}
853 853
854void ICommonStateGetter::PerformSystemButtonPressingIfInFocus(Kernel::HLERequestContext& ctx) { 854void ICommonStateGetter::PerformSystemButtonPressingIfInFocus(HLERequestContext& ctx) {
855 IPC::RequestParser rp{ctx}; 855 IPC::RequestParser rp{ctx};
856 const auto system_button{rp.PopEnum<SystemButtonType>()}; 856 const auto system_button{rp.PopEnum<SystemButtonType>()};
857 857
@@ -862,7 +862,7 @@ void ICommonStateGetter::PerformSystemButtonPressingIfInFocus(Kernel::HLERequest
862} 862}
863 863
864void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled( 864void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(
865 Kernel::HLERequestContext& ctx) { 865 HLERequestContext& ctx) {
866 LOG_WARNING(Service_AM, "(STUBBED) called"); 866 LOG_WARNING(Service_AM, "(STUBBED) called");
867 867
868 IPC::ResponseBuilder rb{ctx, 2}; 868 IPC::ResponseBuilder rb{ctx, 2};
@@ -910,7 +910,7 @@ void IStorage::Register() {
910 910
911IStorage::~IStorage() = default; 911IStorage::~IStorage() = default;
912 912
913void IStorage::Open(Kernel::HLERequestContext& ctx) { 913void IStorage::Open(HLERequestContext& ctx) {
914 LOG_DEBUG(Service_AM, "called"); 914 LOG_DEBUG(Service_AM, "called");
915 915
916 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 916 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -919,7 +919,7 @@ void IStorage::Open(Kernel::HLERequestContext& ctx) {
919 rb.PushIpcInterface<IStorageAccessor>(system, *this); 919 rb.PushIpcInterface<IStorageAccessor>(system, *this);
920} 920}
921 921
922void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { 922void ICommonStateGetter::GetOperationMode(HLERequestContext& ctx) {
923 const bool use_docked_mode{Settings::values.use_docked_mode.GetValue()}; 923 const bool use_docked_mode{Settings::values.use_docked_mode.GetValue()};
924 LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode); 924 LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode);
925 925
@@ -928,7 +928,7 @@ void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
928 rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld)); 928 rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld));
929} 929}
930 930
931void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) { 931void ICommonStateGetter::GetPerformanceMode(HLERequestContext& ctx) {
932 LOG_DEBUG(Service_AM, "called"); 932 LOG_DEBUG(Service_AM, "called");
933 933
934 IPC::ResponseBuilder rb{ctx, 3}; 934 IPC::ResponseBuilder rb{ctx, 3};
@@ -968,7 +968,7 @@ public:
968 } 968 }
969 969
970private: 970private:
971 void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) { 971 void GetAppletStateChangedEvent(HLERequestContext& ctx) {
972 LOG_DEBUG(Service_AM, "called"); 972 LOG_DEBUG(Service_AM, "called");
973 973
974 IPC::ResponseBuilder rb{ctx, 2, 1}; 974 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -976,7 +976,7 @@ private:
976 rb.PushCopyObjects(applet->GetBroker().GetStateChangedEvent()); 976 rb.PushCopyObjects(applet->GetBroker().GetStateChangedEvent());
977 } 977 }
978 978
979 void IsCompleted(Kernel::HLERequestContext& ctx) { 979 void IsCompleted(HLERequestContext& ctx) {
980 LOG_DEBUG(Service_AM, "called"); 980 LOG_DEBUG(Service_AM, "called");
981 981
982 IPC::ResponseBuilder rb{ctx, 3}; 982 IPC::ResponseBuilder rb{ctx, 3};
@@ -984,21 +984,21 @@ private:
984 rb.Push<u32>(applet->TransactionComplete()); 984 rb.Push<u32>(applet->TransactionComplete());
985 } 985 }
986 986
987 void GetResult(Kernel::HLERequestContext& ctx) { 987 void GetResult(HLERequestContext& ctx) {
988 LOG_DEBUG(Service_AM, "called"); 988 LOG_DEBUG(Service_AM, "called");
989 989
990 IPC::ResponseBuilder rb{ctx, 2}; 990 IPC::ResponseBuilder rb{ctx, 2};
991 rb.Push(applet->GetStatus()); 991 rb.Push(applet->GetStatus());
992 } 992 }
993 993
994 void PresetLibraryAppletGpuTimeSliceZero(Kernel::HLERequestContext& ctx) { 994 void PresetLibraryAppletGpuTimeSliceZero(HLERequestContext& ctx) {
995 LOG_WARNING(Service_AM, "(STUBBED) called"); 995 LOG_WARNING(Service_AM, "(STUBBED) called");
996 996
997 IPC::ResponseBuilder rb{ctx, 2}; 997 IPC::ResponseBuilder rb{ctx, 2};
998 rb.Push(ResultSuccess); 998 rb.Push(ResultSuccess);
999 } 999 }
1000 1000
1001 void Start(Kernel::HLERequestContext& ctx) { 1001 void Start(HLERequestContext& ctx) {
1002 LOG_DEBUG(Service_AM, "called"); 1002 LOG_DEBUG(Service_AM, "called");
1003 1003
1004 ASSERT(applet != nullptr); 1004 ASSERT(applet != nullptr);
@@ -1010,7 +1010,7 @@ private:
1010 rb.Push(ResultSuccess); 1010 rb.Push(ResultSuccess);
1011 } 1011 }
1012 1012
1013 void PushInData(Kernel::HLERequestContext& ctx) { 1013 void PushInData(HLERequestContext& ctx) {
1014 LOG_DEBUG(Service_AM, "called"); 1014 LOG_DEBUG(Service_AM, "called");
1015 1015
1016 IPC::RequestParser rp{ctx}; 1016 IPC::RequestParser rp{ctx};
@@ -1020,7 +1020,7 @@ private:
1020 rb.Push(ResultSuccess); 1020 rb.Push(ResultSuccess);
1021 } 1021 }
1022 1022
1023 void PopOutData(Kernel::HLERequestContext& ctx) { 1023 void PopOutData(HLERequestContext& ctx) {
1024 LOG_DEBUG(Service_AM, "called"); 1024 LOG_DEBUG(Service_AM, "called");
1025 1025
1026 auto storage = applet->GetBroker().PopNormalDataToGame(); 1026 auto storage = applet->GetBroker().PopNormalDataToGame();
@@ -1028,7 +1028,7 @@ private:
1028 LOG_DEBUG(Service_AM, 1028 LOG_DEBUG(Service_AM,
1029 "storage is a nullptr. There is no data in the current normal channel"); 1029 "storage is a nullptr. There is no data in the current normal channel");
1030 IPC::ResponseBuilder rb{ctx, 2}; 1030 IPC::ResponseBuilder rb{ctx, 2};
1031 rb.Push(ERR_NO_DATA_IN_CHANNEL); 1031 rb.Push(AM::ResultNoDataInChannel);
1032 return; 1032 return;
1033 } 1033 }
1034 1034
@@ -1037,7 +1037,7 @@ private:
1037 rb.PushIpcInterface<IStorage>(std::move(storage)); 1037 rb.PushIpcInterface<IStorage>(std::move(storage));
1038 } 1038 }
1039 1039
1040 void PushInteractiveInData(Kernel::HLERequestContext& ctx) { 1040 void PushInteractiveInData(HLERequestContext& ctx) {
1041 LOG_DEBUG(Service_AM, "called"); 1041 LOG_DEBUG(Service_AM, "called");
1042 1042
1043 IPC::RequestParser rp{ctx}; 1043 IPC::RequestParser rp{ctx};
@@ -1051,7 +1051,7 @@ private:
1051 rb.Push(ResultSuccess); 1051 rb.Push(ResultSuccess);
1052 } 1052 }
1053 1053
1054 void PopInteractiveOutData(Kernel::HLERequestContext& ctx) { 1054 void PopInteractiveOutData(HLERequestContext& ctx) {
1055 LOG_DEBUG(Service_AM, "called"); 1055 LOG_DEBUG(Service_AM, "called");
1056 1056
1057 auto storage = applet->GetBroker().PopInteractiveDataToGame(); 1057 auto storage = applet->GetBroker().PopInteractiveDataToGame();
@@ -1059,7 +1059,7 @@ private:
1059 LOG_DEBUG(Service_AM, 1059 LOG_DEBUG(Service_AM,
1060 "storage is a nullptr. There is no data in the current interactive channel"); 1060 "storage is a nullptr. There is no data in the current interactive channel");
1061 IPC::ResponseBuilder rb{ctx, 2}; 1061 IPC::ResponseBuilder rb{ctx, 2};
1062 rb.Push(ERR_NO_DATA_IN_CHANNEL); 1062 rb.Push(AM::ResultNoDataInChannel);
1063 return; 1063 return;
1064 } 1064 }
1065 1065
@@ -1068,7 +1068,7 @@ private:
1068 rb.PushIpcInterface<IStorage>(std::move(storage)); 1068 rb.PushIpcInterface<IStorage>(std::move(storage));
1069 } 1069 }
1070 1070
1071 void GetPopOutDataEvent(Kernel::HLERequestContext& ctx) { 1071 void GetPopOutDataEvent(HLERequestContext& ctx) {
1072 LOG_DEBUG(Service_AM, "called"); 1072 LOG_DEBUG(Service_AM, "called");
1073 1073
1074 IPC::ResponseBuilder rb{ctx, 2, 1}; 1074 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -1076,7 +1076,7 @@ private:
1076 rb.PushCopyObjects(applet->GetBroker().GetNormalDataEvent()); 1076 rb.PushCopyObjects(applet->GetBroker().GetNormalDataEvent());
1077 } 1077 }
1078 1078
1079 void GetPopInteractiveOutDataEvent(Kernel::HLERequestContext& ctx) { 1079 void GetPopInteractiveOutDataEvent(HLERequestContext& ctx) {
1080 LOG_DEBUG(Service_AM, "called"); 1080 LOG_DEBUG(Service_AM, "called");
1081 1081
1082 IPC::ResponseBuilder rb{ctx, 2, 1}; 1082 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -1084,7 +1084,7 @@ private:
1084 rb.PushCopyObjects(applet->GetBroker().GetInteractiveDataEvent()); 1084 rb.PushCopyObjects(applet->GetBroker().GetInteractiveDataEvent());
1085 } 1085 }
1086 1086
1087 void GetIndirectLayerConsumerHandle(Kernel::HLERequestContext& ctx) { 1087 void GetIndirectLayerConsumerHandle(HLERequestContext& ctx) {
1088 LOG_WARNING(Service_AM, "(STUBBED) called"); 1088 LOG_WARNING(Service_AM, "(STUBBED) called");
1089 1089
1090 // We require a non-zero handle to be valid. Using 0xdeadbeef allows us to trace if this is 1090 // We require a non-zero handle to be valid. Using 0xdeadbeef allows us to trace if this is
@@ -1114,7 +1114,7 @@ IStorageAccessor::IStorageAccessor(Core::System& system_, IStorage& backing_)
1114 1114
1115IStorageAccessor::~IStorageAccessor() = default; 1115IStorageAccessor::~IStorageAccessor() = default;
1116 1116
1117void IStorageAccessor::GetSize(Kernel::HLERequestContext& ctx) { 1117void IStorageAccessor::GetSize(HLERequestContext& ctx) {
1118 LOG_DEBUG(Service_AM, "called"); 1118 LOG_DEBUG(Service_AM, "called");
1119 1119
1120 IPC::ResponseBuilder rb{ctx, 4}; 1120 IPC::ResponseBuilder rb{ctx, 4};
@@ -1123,7 +1123,7 @@ void IStorageAccessor::GetSize(Kernel::HLERequestContext& ctx) {
1123 rb.Push(static_cast<u64>(backing.GetSize())); 1123 rb.Push(static_cast<u64>(backing.GetSize()));
1124} 1124}
1125 1125
1126void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) { 1126void IStorageAccessor::Write(HLERequestContext& ctx) {
1127 IPC::RequestParser rp{ctx}; 1127 IPC::RequestParser rp{ctx};
1128 1128
1129 const u64 offset{rp.Pop<u64>()}; 1129 const u64 offset{rp.Pop<u64>()};
@@ -1138,7 +1138,7 @@ void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) {
1138 backing.GetSize(), size, offset); 1138 backing.GetSize(), size, offset);
1139 1139
1140 IPC::ResponseBuilder rb{ctx, 2}; 1140 IPC::ResponseBuilder rb{ctx, 2};
1141 rb.Push(ERR_SIZE_OUT_OF_BOUNDS); 1141 rb.Push(AM::ResultInvalidOffset);
1142 return; 1142 return;
1143 } 1143 }
1144 1144
@@ -1148,7 +1148,7 @@ void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) {
1148 rb.Push(ResultSuccess); 1148 rb.Push(ResultSuccess);
1149} 1149}
1150 1150
1151void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) { 1151void IStorageAccessor::Read(HLERequestContext& ctx) {
1152 IPC::RequestParser rp{ctx}; 1152 IPC::RequestParser rp{ctx};
1153 1153
1154 const u64 offset{rp.Pop<u64>()}; 1154 const u64 offset{rp.Pop<u64>()};
@@ -1161,7 +1161,7 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) {
1161 backing.GetSize(), size, offset); 1161 backing.GetSize(), size, offset);
1162 1162
1163 IPC::ResponseBuilder rb{ctx, 2}; 1163 IPC::ResponseBuilder rb{ctx, 2};
1164 rb.Push(ERR_SIZE_OUT_OF_BOUNDS); 1164 rb.Push(AM::ResultInvalidOffset);
1165 return; 1165 return;
1166 } 1166 }
1167 1167
@@ -1186,7 +1186,7 @@ ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_)
1186 1186
1187ILibraryAppletCreator::~ILibraryAppletCreator() = default; 1187ILibraryAppletCreator::~ILibraryAppletCreator() = default;
1188 1188
1189void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) { 1189void ILibraryAppletCreator::CreateLibraryApplet(HLERequestContext& ctx) {
1190 IPC::RequestParser rp{ctx}; 1190 IPC::RequestParser rp{ctx};
1191 1191
1192 const auto applet_id = rp.PopRaw<Applets::AppletId>(); 1192 const auto applet_id = rp.PopRaw<Applets::AppletId>();
@@ -1212,7 +1212,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
1212 rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet); 1212 rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet);
1213} 1213}
1214 1214
1215void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { 1215void ILibraryAppletCreator::CreateStorage(HLERequestContext& ctx) {
1216 IPC::RequestParser rp{ctx}; 1216 IPC::RequestParser rp{ctx};
1217 1217
1218 const s64 size{rp.Pop<s64>()}; 1218 const s64 size{rp.Pop<s64>()};
@@ -1233,7 +1233,7 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
1233 rb.PushIpcInterface<IStorage>(system, std::move(buffer)); 1233 rb.PushIpcInterface<IStorage>(system, std::move(buffer));
1234} 1234}
1235 1235
1236void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) { 1236void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx) {
1237 IPC::RequestParser rp{ctx}; 1237 IPC::RequestParser rp{ctx};
1238 1238
1239 struct Parameters { 1239 struct Parameters {
@@ -1264,16 +1264,15 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
1264 return; 1264 return;
1265 } 1265 }
1266 1266
1267 const u8* const mem_begin = system.Memory().GetPointer(transfer_mem->GetSourceAddress()); 1267 std::vector<u8> memory(transfer_mem->GetSize());
1268 const u8* const mem_end = mem_begin + transfer_mem->GetSize(); 1268 system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size());
1269 std::vector<u8> memory{mem_begin, mem_end};
1270 1269
1271 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1270 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1272 rb.Push(ResultSuccess); 1271 rb.Push(ResultSuccess);
1273 rb.PushIpcInterface<IStorage>(system, std::move(memory)); 1272 rb.PushIpcInterface<IStorage>(system, std::move(memory));
1274} 1273}
1275 1274
1276void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx) { 1275void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) {
1277 IPC::RequestParser rp{ctx}; 1276 IPC::RequestParser rp{ctx};
1278 1277
1279 const s64 size{rp.Pop<s64>()}; 1278 const s64 size{rp.Pop<s64>()};
@@ -1298,9 +1297,8 @@ void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx)
1298 return; 1297 return;
1299 } 1298 }
1300 1299
1301 const u8* const mem_begin = system.Memory().GetPointer(transfer_mem->GetSourceAddress()); 1300 std::vector<u8> memory(transfer_mem->GetSize());
1302 const u8* const mem_end = mem_begin + transfer_mem->GetSize(); 1301 system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size());
1303 std::vector<u8> memory{mem_begin, mem_end};
1304 1302
1305 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1303 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1306 rb.Push(ResultSuccess); 1304 rb.Push(ResultSuccess);
@@ -1396,29 +1394,28 @@ IApplicationFunctions::~IApplicationFunctions() {
1396 service_context.CloseEvent(health_warning_disappeared_system_event); 1394 service_context.CloseEvent(health_warning_disappeared_system_event);
1397} 1395}
1398 1396
1399void IApplicationFunctions::EnableApplicationCrashReport(Kernel::HLERequestContext& ctx) { 1397void IApplicationFunctions::EnableApplicationCrashReport(HLERequestContext& ctx) {
1400 LOG_WARNING(Service_AM, "(STUBBED) called"); 1398 LOG_WARNING(Service_AM, "(STUBBED) called");
1401 1399
1402 IPC::ResponseBuilder rb{ctx, 2}; 1400 IPC::ResponseBuilder rb{ctx, 2};
1403 rb.Push(ResultSuccess); 1401 rb.Push(ResultSuccess);
1404} 1402}
1405 1403
1406void IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer( 1404void IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer(HLERequestContext& ctx) {
1407 Kernel::HLERequestContext& ctx) {
1408 LOG_WARNING(Service_AM, "(STUBBED) called"); 1405 LOG_WARNING(Service_AM, "(STUBBED) called");
1409 1406
1410 IPC::ResponseBuilder rb{ctx, 2}; 1407 IPC::ResponseBuilder rb{ctx, 2};
1411 rb.Push(ResultSuccess); 1408 rb.Push(ResultSuccess);
1412} 1409}
1413 1410
1414void IApplicationFunctions::SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx) { 1411void IApplicationFunctions::SetApplicationCopyrightImage(HLERequestContext& ctx) {
1415 LOG_WARNING(Service_AM, "(STUBBED) called"); 1412 LOG_WARNING(Service_AM, "(STUBBED) called");
1416 1413
1417 IPC::ResponseBuilder rb{ctx, 2}; 1414 IPC::ResponseBuilder rb{ctx, 2};
1418 rb.Push(ResultSuccess); 1415 rb.Push(ResultSuccess);
1419} 1416}
1420 1417
1421void IApplicationFunctions::SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx) { 1418void IApplicationFunctions::SetApplicationCopyrightVisibility(HLERequestContext& ctx) {
1422 IPC::RequestParser rp{ctx}; 1419 IPC::RequestParser rp{ctx};
1423 const auto is_visible = rp.Pop<bool>(); 1420 const auto is_visible = rp.Pop<bool>();
1424 1421
@@ -1428,37 +1425,35 @@ void IApplicationFunctions::SetApplicationCopyrightVisibility(Kernel::HLERequest
1428 rb.Push(ResultSuccess); 1425 rb.Push(ResultSuccess);
1429} 1426}
1430 1427
1431void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed( 1428void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) {
1432 Kernel::HLERequestContext& ctx) {
1433 LOG_WARNING(Service_AM, "(STUBBED) called"); 1429 LOG_WARNING(Service_AM, "(STUBBED) called");
1434 1430
1435 IPC::ResponseBuilder rb{ctx, 2}; 1431 IPC::ResponseBuilder rb{ctx, 2};
1436 rb.Push(ResultSuccess); 1432 rb.Push(ResultSuccess);
1437} 1433}
1438 1434
1439void IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed( 1435void IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) {
1440 Kernel::HLERequestContext& ctx) {
1441 LOG_WARNING(Service_AM, "(STUBBED) called"); 1436 LOG_WARNING(Service_AM, "(STUBBED) called");
1442 1437
1443 IPC::ResponseBuilder rb{ctx, 2}; 1438 IPC::ResponseBuilder rb{ctx, 2};
1444 rb.Push(ResultSuccess); 1439 rb.Push(ResultSuccess);
1445} 1440}
1446 1441
1447void IApplicationFunctions::BeginBlockingHomeButton(Kernel::HLERequestContext& ctx) { 1442void IApplicationFunctions::BeginBlockingHomeButton(HLERequestContext& ctx) {
1448 LOG_WARNING(Service_AM, "(STUBBED) called"); 1443 LOG_WARNING(Service_AM, "(STUBBED) called");
1449 1444
1450 IPC::ResponseBuilder rb{ctx, 2}; 1445 IPC::ResponseBuilder rb{ctx, 2};
1451 rb.Push(ResultSuccess); 1446 rb.Push(ResultSuccess);
1452} 1447}
1453 1448
1454void IApplicationFunctions::EndBlockingHomeButton(Kernel::HLERequestContext& ctx) { 1449void IApplicationFunctions::EndBlockingHomeButton(HLERequestContext& ctx) {
1455 LOG_WARNING(Service_AM, "(STUBBED) called"); 1450 LOG_WARNING(Service_AM, "(STUBBED) called");
1456 1451
1457 IPC::ResponseBuilder rb{ctx, 2}; 1452 IPC::ResponseBuilder rb{ctx, 2};
1458 rb.Push(ResultSuccess); 1453 rb.Push(ResultSuccess);
1459} 1454}
1460 1455
1461void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) { 1456void IApplicationFunctions::PopLaunchParameter(HLERequestContext& ctx) {
1462 IPC::RequestParser rp{ctx}; 1457 IPC::RequestParser rp{ctx};
1463 const auto kind = rp.PopEnum<LaunchParameterKind>(); 1458 const auto kind = rp.PopEnum<LaunchParameterKind>();
1464 1459
@@ -1507,18 +1502,17 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
1507 1502
1508 LOG_ERROR(Service_AM, "Attempted to load launch parameter but none was found!"); 1503 LOG_ERROR(Service_AM, "Attempted to load launch parameter but none was found!");
1509 IPC::ResponseBuilder rb{ctx, 2}; 1504 IPC::ResponseBuilder rb{ctx, 2};
1510 rb.Push(ERR_NO_DATA_IN_CHANNEL); 1505 rb.Push(AM::ResultNoDataInChannel);
1511} 1506}
1512 1507
1513void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest( 1508void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) {
1514 Kernel::HLERequestContext& ctx) {
1515 LOG_WARNING(Service_AM, "(STUBBED) called"); 1509 LOG_WARNING(Service_AM, "(STUBBED) called");
1516 1510
1517 IPC::ResponseBuilder rb{ctx, 2}; 1511 IPC::ResponseBuilder rb{ctx, 2};
1518 rb.Push(ResultSuccess); 1512 rb.Push(ResultSuccess);
1519} 1513}
1520 1514
1521void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { 1515void IApplicationFunctions::EnsureSaveData(HLERequestContext& ctx) {
1522 IPC::RequestParser rp{ctx}; 1516 IPC::RequestParser rp{ctx};
1523 u128 user_id = rp.PopRaw<u128>(); 1517 u128 user_id = rp.PopRaw<u128>();
1524 1518
@@ -1536,7 +1530,7 @@ void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) {
1536 rb.Push<u64>(0); 1530 rb.Push<u64>(0);
1537} 1531}
1538 1532
1539void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) { 1533void IApplicationFunctions::SetTerminateResult(HLERequestContext& ctx) {
1540 // Takes an input u32 Result, no output. 1534 // Takes an input u32 Result, no output.
1541 // For example, in some cases official apps use this with error 0x2A2 then 1535 // For example, in some cases official apps use this with error 0x2A2 then
1542 // uses svcBreak. 1536 // uses svcBreak.
@@ -1549,7 +1543,7 @@ void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
1549 rb.Push(ResultSuccess); 1543 rb.Push(ResultSuccess);
1550} 1544}
1551 1545
1552void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) { 1546void IApplicationFunctions::GetDisplayVersion(HLERequestContext& ctx) {
1553 LOG_DEBUG(Service_AM, "called"); 1547 LOG_DEBUG(Service_AM, "called");
1554 1548
1555 std::array<u8, 0x10> version_string{}; 1549 std::array<u8, 0x10> version_string{};
@@ -1583,7 +1577,7 @@ void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
1583 rb.PushRaw(version_string); 1577 rb.PushRaw(version_string);
1584} 1578}
1585 1579
1586void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { 1580void IApplicationFunctions::GetDesiredLanguage(HLERequestContext& ctx) {
1587 // TODO(bunnei): This should be configurable 1581 // TODO(bunnei): This should be configurable
1588 LOG_DEBUG(Service_AM, "called"); 1582 LOG_DEBUG(Service_AM, "called");
1589 1583
@@ -1639,7 +1633,7 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
1639 rb.Push(*res_code); 1633 rb.Push(*res_code);
1640} 1634}
1641 1635
1642void IApplicationFunctions::IsGamePlayRecordingSupported(Kernel::HLERequestContext& ctx) { 1636void IApplicationFunctions::IsGamePlayRecordingSupported(HLERequestContext& ctx) {
1643 LOG_WARNING(Service_AM, "(STUBBED) called"); 1637 LOG_WARNING(Service_AM, "(STUBBED) called");
1644 1638
1645 constexpr bool gameplay_recording_supported = false; 1639 constexpr bool gameplay_recording_supported = false;
@@ -1649,21 +1643,21 @@ void IApplicationFunctions::IsGamePlayRecordingSupported(Kernel::HLERequestConte
1649 rb.Push(gameplay_recording_supported); 1643 rb.Push(gameplay_recording_supported);
1650} 1644}
1651 1645
1652void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) { 1646void IApplicationFunctions::InitializeGamePlayRecording(HLERequestContext& ctx) {
1653 LOG_WARNING(Service_AM, "(STUBBED) called"); 1647 LOG_WARNING(Service_AM, "(STUBBED) called");
1654 1648
1655 IPC::ResponseBuilder rb{ctx, 2}; 1649 IPC::ResponseBuilder rb{ctx, 2};
1656 rb.Push(ResultSuccess); 1650 rb.Push(ResultSuccess);
1657} 1651}
1658 1652
1659void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) { 1653void IApplicationFunctions::SetGamePlayRecordingState(HLERequestContext& ctx) {
1660 LOG_WARNING(Service_AM, "(STUBBED) called"); 1654 LOG_WARNING(Service_AM, "(STUBBED) called");
1661 1655
1662 IPC::ResponseBuilder rb{ctx, 2}; 1656 IPC::ResponseBuilder rb{ctx, 2};
1663 rb.Push(ResultSuccess); 1657 rb.Push(ResultSuccess);
1664} 1658}
1665 1659
1666void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) { 1660void IApplicationFunctions::NotifyRunning(HLERequestContext& ctx) {
1667 LOG_WARNING(Service_AM, "(STUBBED) called"); 1661 LOG_WARNING(Service_AM, "(STUBBED) called");
1668 1662
1669 IPC::ResponseBuilder rb{ctx, 3}; 1663 IPC::ResponseBuilder rb{ctx, 3};
@@ -1671,7 +1665,7 @@ void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) {
1671 rb.Push<u8>(0); // Unknown, seems to be ignored by official processes 1665 rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
1672} 1666}
1673 1667
1674void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) { 1668void IApplicationFunctions::GetPseudoDeviceId(HLERequestContext& ctx) {
1675 LOG_WARNING(Service_AM, "(STUBBED) called"); 1669 LOG_WARNING(Service_AM, "(STUBBED) called");
1676 1670
1677 IPC::ResponseBuilder rb{ctx, 6}; 1671 IPC::ResponseBuilder rb{ctx, 6};
@@ -1682,7 +1676,7 @@ void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
1682 rb.Push<u64>(0); 1676 rb.Push<u64>(0);
1683} 1677}
1684 1678
1685void IApplicationFunctions::ExtendSaveData(Kernel::HLERequestContext& ctx) { 1679void IApplicationFunctions::ExtendSaveData(HLERequestContext& ctx) {
1686 struct Parameters { 1680 struct Parameters {
1687 FileSys::SaveDataType type; 1681 FileSys::SaveDataType type;
1688 u128 user_id; 1682 u128 user_id;
@@ -1711,7 +1705,7 @@ void IApplicationFunctions::ExtendSaveData(Kernel::HLERequestContext& ctx) {
1711 rb.Push<u64>(0); 1705 rb.Push<u64>(0);
1712} 1706}
1713 1707
1714void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) { 1708void IApplicationFunctions::GetSaveDataSize(HLERequestContext& ctx) {
1715 struct Parameters { 1709 struct Parameters {
1716 FileSys::SaveDataType type; 1710 FileSys::SaveDataType type;
1717 u128 user_id; 1711 u128 user_id;
@@ -1733,7 +1727,7 @@ void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) {
1733 rb.Push(size.journal); 1727 rb.Push(size.journal);
1734} 1728}
1735 1729
1736void IApplicationFunctions::QueryApplicationPlayStatistics(Kernel::HLERequestContext& ctx) { 1730void IApplicationFunctions::QueryApplicationPlayStatistics(HLERequestContext& ctx) {
1737 LOG_WARNING(Service_AM, "(STUBBED) called"); 1731 LOG_WARNING(Service_AM, "(STUBBED) called");
1738 1732
1739 IPC::ResponseBuilder rb{ctx, 3}; 1733 IPC::ResponseBuilder rb{ctx, 3};
@@ -1741,7 +1735,7 @@ void IApplicationFunctions::QueryApplicationPlayStatistics(Kernel::HLERequestCon
1741 rb.Push<u32>(0); 1735 rb.Push<u32>(0);
1742} 1736}
1743 1737
1744void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx) { 1738void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(HLERequestContext& ctx) {
1745 LOG_WARNING(Service_AM, "(STUBBED) called"); 1739 LOG_WARNING(Service_AM, "(STUBBED) called");
1746 1740
1747 IPC::ResponseBuilder rb{ctx, 3}; 1741 IPC::ResponseBuilder rb{ctx, 3};
@@ -1749,7 +1743,7 @@ void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(Kernel::HLEReque
1749 rb.Push<u32>(0); 1743 rb.Push<u32>(0);
1750} 1744}
1751 1745
1752void IApplicationFunctions::ExecuteProgram(Kernel::HLERequestContext& ctx) { 1746void IApplicationFunctions::ExecuteProgram(HLERequestContext& ctx) {
1753 LOG_WARNING(Service_AM, "(STUBBED) called"); 1747 LOG_WARNING(Service_AM, "(STUBBED) called");
1754 1748
1755 IPC::RequestParser rp{ctx}; 1749 IPC::RequestParser rp{ctx};
@@ -1763,21 +1757,21 @@ void IApplicationFunctions::ExecuteProgram(Kernel::HLERequestContext& ctx) {
1763 system.ExecuteProgram(program_index); 1757 system.ExecuteProgram(program_index);
1764} 1758}
1765 1759
1766void IApplicationFunctions::ClearUserChannel(Kernel::HLERequestContext& ctx) { 1760void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) {
1767 LOG_WARNING(Service_AM, "(STUBBED) called"); 1761 LOG_WARNING(Service_AM, "(STUBBED) called");
1768 1762
1769 IPC::ResponseBuilder rb{ctx, 2}; 1763 IPC::ResponseBuilder rb{ctx, 2};
1770 rb.Push(ResultSuccess); 1764 rb.Push(ResultSuccess);
1771} 1765}
1772 1766
1773void IApplicationFunctions::UnpopToUserChannel(Kernel::HLERequestContext& ctx) { 1767void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) {
1774 LOG_WARNING(Service_AM, "(STUBBED) called"); 1768 LOG_WARNING(Service_AM, "(STUBBED) called");
1775 1769
1776 IPC::ResponseBuilder rb{ctx, 2}; 1770 IPC::ResponseBuilder rb{ctx, 2};
1777 rb.Push(ResultSuccess); 1771 rb.Push(ResultSuccess);
1778} 1772}
1779 1773
1780void IApplicationFunctions::GetPreviousProgramIndex(Kernel::HLERequestContext& ctx) { 1774void IApplicationFunctions::GetPreviousProgramIndex(HLERequestContext& ctx) {
1781 LOG_WARNING(Service_AM, "(STUBBED) called"); 1775 LOG_WARNING(Service_AM, "(STUBBED) called");
1782 1776
1783 IPC::ResponseBuilder rb{ctx, 3}; 1777 IPC::ResponseBuilder rb{ctx, 3};
@@ -1785,7 +1779,7 @@ void IApplicationFunctions::GetPreviousProgramIndex(Kernel::HLERequestContext& c
1785 rb.Push<s32>(previous_program_index); 1779 rb.Push<s32>(previous_program_index);
1786} 1780}
1787 1781
1788void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx) { 1782void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(HLERequestContext& ctx) {
1789 LOG_WARNING(Service_AM, "(STUBBED) called"); 1783 LOG_WARNING(Service_AM, "(STUBBED) called");
1790 1784
1791 IPC::ResponseBuilder rb{ctx, 2, 1}; 1785 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -1793,7 +1787,7 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon
1793 rb.PushCopyObjects(gpu_error_detected_event->GetReadableEvent()); 1787 rb.PushCopyObjects(gpu_error_detected_event->GetReadableEvent());
1794} 1788}
1795 1789
1796void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) { 1790void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(HLERequestContext& ctx) {
1797 LOG_DEBUG(Service_AM, "called"); 1791 LOG_DEBUG(Service_AM, "called");
1798 1792
1799 IPC::ResponseBuilder rb{ctx, 2, 1}; 1793 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -1801,15 +1795,14 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe
1801 rb.PushCopyObjects(friend_invitation_storage_channel_event->GetReadableEvent()); 1795 rb.PushCopyObjects(friend_invitation_storage_channel_event->GetReadableEvent());
1802} 1796}
1803 1797
1804void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel( 1798void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(HLERequestContext& ctx) {
1805 Kernel::HLERequestContext& ctx) {
1806 LOG_WARNING(Service_AM, "(STUBBED) called"); 1799 LOG_WARNING(Service_AM, "(STUBBED) called");
1807 1800
1808 IPC::ResponseBuilder rb{ctx, 2}; 1801 IPC::ResponseBuilder rb{ctx, 2};
1809 rb.Push(ERR_NO_DATA_IN_CHANNEL); 1802 rb.Push(AM::ResultNoDataInChannel);
1810} 1803}
1811 1804
1812void IApplicationFunctions::GetNotificationStorageChannelEvent(Kernel::HLERequestContext& ctx) { 1805void IApplicationFunctions::GetNotificationStorageChannelEvent(HLERequestContext& ctx) {
1813 LOG_DEBUG(Service_AM, "called"); 1806 LOG_DEBUG(Service_AM, "called");
1814 1807
1815 IPC::ResponseBuilder rb{ctx, 2, 1}; 1808 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -1817,7 +1810,7 @@ void IApplicationFunctions::GetNotificationStorageChannelEvent(Kernel::HLEReques
1817 rb.PushCopyObjects(notification_storage_channel_event->GetReadableEvent()); 1810 rb.PushCopyObjects(notification_storage_channel_event->GetReadableEvent());
1818} 1811}
1819 1812
1820void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERequestContext& ctx) { 1813void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(HLERequestContext& ctx) {
1821 LOG_DEBUG(Service_AM, "called"); 1814 LOG_DEBUG(Service_AM, "called");
1822 1815
1823 IPC::ResponseBuilder rb{ctx, 2, 1}; 1816 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -1825,24 +1818,28 @@ void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERe
1825 rb.PushCopyObjects(health_warning_disappeared_system_event->GetReadableEvent()); 1818 rb.PushCopyObjects(health_warning_disappeared_system_event->GetReadableEvent());
1826} 1819}
1827 1820
1828void IApplicationFunctions::PrepareForJit(Kernel::HLERequestContext& ctx) { 1821void IApplicationFunctions::PrepareForJit(HLERequestContext& ctx) {
1829 LOG_WARNING(Service_AM, "(STUBBED) called"); 1822 LOG_WARNING(Service_AM, "(STUBBED) called");
1830 1823
1831 IPC::ResponseBuilder rb{ctx, 2}; 1824 IPC::ResponseBuilder rb{ctx, 2};
1832 rb.Push(ResultSuccess); 1825 rb.Push(ResultSuccess);
1833} 1826}
1834 1827
1835void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, 1828void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) {
1836 Core::System& system) {
1837 auto message_queue = std::make_shared<AppletMessageQueue>(system); 1829 auto message_queue = std::make_shared<AppletMessageQueue>(system);
1838 // Needed on game boot 1830 // Needed on game boot
1839 message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); 1831 message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
1840 1832
1841 std::make_shared<AppletAE>(nvflinger, message_queue, system)->InstallAsService(service_manager); 1833 auto server_manager = std::make_unique<ServerManager>(system);
1842 std::make_shared<AppletOE>(nvflinger, message_queue, system)->InstallAsService(service_manager); 1834
1843 std::make_shared<IdleSys>(system)->InstallAsService(service_manager); 1835 server_manager->RegisterNamedService(
1844 std::make_shared<OMM>(system)->InstallAsService(service_manager); 1836 "appletAE", std::make_shared<AppletAE>(nvnflinger, message_queue, system));
1845 std::make_shared<SPSM>(system)->InstallAsService(service_manager); 1837 server_manager->RegisterNamedService(
1838 "appletOE", std::make_shared<AppletOE>(nvnflinger, message_queue, system));
1839 server_manager->RegisterNamedService("idle:sys", std::make_shared<IdleSys>(system));
1840 server_manager->RegisterNamedService("omm", std::make_shared<OMM>(system));
1841 server_manager->RegisterNamedService("spsm", std::make_shared<SPSM>(system));
1842 ServerManager::RunServer(std::move(server_manager));
1846} 1843}
1847 1844
1848IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_) 1845IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
@@ -1878,14 +1875,14 @@ IHomeMenuFunctions::~IHomeMenuFunctions() {
1878 service_context.CloseEvent(pop_from_general_channel_event); 1875 service_context.CloseEvent(pop_from_general_channel_event);
1879} 1876}
1880 1877
1881void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) { 1878void IHomeMenuFunctions::RequestToGetForeground(HLERequestContext& ctx) {
1882 LOG_WARNING(Service_AM, "(STUBBED) called"); 1879 LOG_WARNING(Service_AM, "(STUBBED) called");
1883 1880
1884 IPC::ResponseBuilder rb{ctx, 2}; 1881 IPC::ResponseBuilder rb{ctx, 2};
1885 rb.Push(ResultSuccess); 1882 rb.Push(ResultSuccess);
1886} 1883}
1887 1884
1888void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx) { 1885void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(HLERequestContext& ctx) {
1889 LOG_WARNING(Service_AM, "(STUBBED) called"); 1886 LOG_WARNING(Service_AM, "(STUBBED) called");
1890 1887
1891 IPC::ResponseBuilder rb{ctx, 2, 1}; 1888 IPC::ResponseBuilder rb{ctx, 2, 1};
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index a0fbfcfc5..0dbc6485e 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -12,11 +12,12 @@
12 12
13namespace Kernel { 13namespace Kernel {
14class KernelCore; 14class KernelCore;
15class KReadableEvent;
15class KTransferMemory; 16class KTransferMemory;
16} // namespace Kernel 17} // namespace Kernel
17 18
18namespace Service::NVFlinger { 19namespace Service::Nvnflinger {
19class NVFlinger; 20class Nvnflinger;
20} 21}
21 22
22namespace Service::AM { 23namespace Service::AM {
@@ -109,8 +110,8 @@ public:
109 ~IWindowController() override; 110 ~IWindowController() override;
110 111
111private: 112private:
112 void GetAppletResourceUserId(Kernel::HLERequestContext& ctx); 113 void GetAppletResourceUserId(HLERequestContext& ctx);
113 void AcquireForegroundRights(Kernel::HLERequestContext& ctx); 114 void AcquireForegroundRights(HLERequestContext& ctx);
114}; 115};
115 116
116class IAudioController final : public ServiceFramework<IAudioController> { 117class IAudioController final : public ServiceFramework<IAudioController> {
@@ -119,11 +120,11 @@ public:
119 ~IAudioController() override; 120 ~IAudioController() override;
120 121
121private: 122private:
122 void SetExpectedMasterVolume(Kernel::HLERequestContext& ctx); 123 void SetExpectedMasterVolume(HLERequestContext& ctx);
123 void GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx); 124 void GetMainAppletExpectedMasterVolume(HLERequestContext& ctx);
124 void GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx); 125 void GetLibraryAppletExpectedMasterVolume(HLERequestContext& ctx);
125 void ChangeMainAppletMasterVolume(Kernel::HLERequestContext& ctx); 126 void ChangeMainAppletMasterVolume(HLERequestContext& ctx);
126 void SetTransparentAudioRate(Kernel::HLERequestContext& ctx); 127 void SetTransparentAudioRate(HLERequestContext& ctx);
127 128
128 static constexpr float min_allowed_volume = 0.0f; 129 static constexpr float min_allowed_volume = 0.0f;
129 static constexpr float max_allowed_volume = 1.0f; 130 static constexpr float max_allowed_volume = 1.0f;
@@ -153,36 +154,36 @@ public:
153 154
154class ISelfController final : public ServiceFramework<ISelfController> { 155class ISelfController final : public ServiceFramework<ISelfController> {
155public: 156public:
156 explicit ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_); 157 explicit ISelfController(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger_);
157 ~ISelfController() override; 158 ~ISelfController() override;
158 159
159private: 160private:
160 void Exit(Kernel::HLERequestContext& ctx); 161 void Exit(HLERequestContext& ctx);
161 void LockExit(Kernel::HLERequestContext& ctx); 162 void LockExit(HLERequestContext& ctx);
162 void UnlockExit(Kernel::HLERequestContext& ctx); 163 void UnlockExit(HLERequestContext& ctx);
163 void EnterFatalSection(Kernel::HLERequestContext& ctx); 164 void EnterFatalSection(HLERequestContext& ctx);
164 void LeaveFatalSection(Kernel::HLERequestContext& ctx); 165 void LeaveFatalSection(HLERequestContext& ctx);
165 void GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx); 166 void GetLibraryAppletLaunchableEvent(HLERequestContext& ctx);
166 void SetScreenShotPermission(Kernel::HLERequestContext& ctx); 167 void SetScreenShotPermission(HLERequestContext& ctx);
167 void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx); 168 void SetOperationModeChangedNotification(HLERequestContext& ctx);
168 void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx); 169 void SetPerformanceModeChangedNotification(HLERequestContext& ctx);
169 void SetFocusHandlingMode(Kernel::HLERequestContext& ctx); 170 void SetFocusHandlingMode(HLERequestContext& ctx);
170 void SetRestartMessageEnabled(Kernel::HLERequestContext& ctx); 171 void SetRestartMessageEnabled(HLERequestContext& ctx);
171 void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx); 172 void SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx);
172 void SetAlbumImageOrientation(Kernel::HLERequestContext& ctx); 173 void SetAlbumImageOrientation(HLERequestContext& ctx);
173 void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx); 174 void CreateManagedDisplayLayer(HLERequestContext& ctx);
174 void CreateManagedDisplaySeparableLayer(Kernel::HLERequestContext& ctx); 175 void CreateManagedDisplaySeparableLayer(HLERequestContext& ctx);
175 void SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx); 176 void SetHandlesRequestToDisplay(HLERequestContext& ctx);
176 void SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx); 177 void SetIdleTimeDetectionExtension(HLERequestContext& ctx);
177 void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx); 178 void GetIdleTimeDetectionExtension(HLERequestContext& ctx);
178 void ReportUserIsActive(Kernel::HLERequestContext& ctx); 179 void ReportUserIsActive(HLERequestContext& ctx);
179 void SetAutoSleepDisabled(Kernel::HLERequestContext& ctx); 180 void SetAutoSleepDisabled(HLERequestContext& ctx);
180 void IsAutoSleepDisabled(Kernel::HLERequestContext& ctx); 181 void IsAutoSleepDisabled(HLERequestContext& ctx);
181 void GetAccumulatedSuspendedTickValue(Kernel::HLERequestContext& ctx); 182 void GetAccumulatedSuspendedTickValue(HLERequestContext& ctx);
182 void GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx); 183 void GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx);
183 void SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx); 184 void SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx);
184 void SaveCurrentScreenshot(Kernel::HLERequestContext& ctx); 185 void SaveCurrentScreenshot(HLERequestContext& ctx);
185 void SetRecordVolumeMuted(Kernel::HLERequestContext& ctx); 186 void SetRecordVolumeMuted(HLERequestContext& ctx);
186 187
187 enum class ScreenshotPermission : u32 { 188 enum class ScreenshotPermission : u32 {
188 Inherit = 0, 189 Inherit = 0,
@@ -190,7 +191,7 @@ private:
190 Disable = 2, 191 Disable = 2,
191 }; 192 };
192 193
193 NVFlinger::NVFlinger& nvflinger; 194 Nvnflinger::Nvnflinger& nvnflinger;
194 195
195 KernelHelpers::ServiceContext service_context; 196 KernelHelpers::ServiceContext service_context;
196 197
@@ -235,22 +236,22 @@ private:
235 CaptureButtonLongPressing, 236 CaptureButtonLongPressing,
236 }; 237 };
237 238
238 void GetEventHandle(Kernel::HLERequestContext& ctx); 239 void GetEventHandle(HLERequestContext& ctx);
239 void ReceiveMessage(Kernel::HLERequestContext& ctx); 240 void ReceiveMessage(HLERequestContext& ctx);
240 void GetCurrentFocusState(Kernel::HLERequestContext& ctx); 241 void GetCurrentFocusState(HLERequestContext& ctx);
241 void GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx); 242 void GetDefaultDisplayResolutionChangeEvent(HLERequestContext& ctx);
242 void GetOperationMode(Kernel::HLERequestContext& ctx); 243 void GetOperationMode(HLERequestContext& ctx);
243 void GetPerformanceMode(Kernel::HLERequestContext& ctx); 244 void GetPerformanceMode(HLERequestContext& ctx);
244 void GetBootMode(Kernel::HLERequestContext& ctx); 245 void GetBootMode(HLERequestContext& ctx);
245 void IsVrModeEnabled(Kernel::HLERequestContext& ctx); 246 void IsVrModeEnabled(HLERequestContext& ctx);
246 void SetVrModeEnabled(Kernel::HLERequestContext& ctx); 247 void SetVrModeEnabled(HLERequestContext& ctx);
247 void SetLcdBacklighOffEnabled(Kernel::HLERequestContext& ctx); 248 void SetLcdBacklighOffEnabled(HLERequestContext& ctx);
248 void BeginVrModeEx(Kernel::HLERequestContext& ctx); 249 void BeginVrModeEx(HLERequestContext& ctx);
249 void EndVrModeEx(Kernel::HLERequestContext& ctx); 250 void EndVrModeEx(HLERequestContext& ctx);
250 void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); 251 void GetDefaultDisplayResolution(HLERequestContext& ctx);
251 void SetCpuBoostMode(Kernel::HLERequestContext& ctx); 252 void SetCpuBoostMode(HLERequestContext& ctx);
252 void PerformSystemButtonPressingIfInFocus(Kernel::HLERequestContext& ctx); 253 void PerformSystemButtonPressingIfInFocus(HLERequestContext& ctx);
253 void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(Kernel::HLERequestContext& ctx); 254 void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(HLERequestContext& ctx);
254 255
255 std::shared_ptr<AppletMessageQueue> msg_queue; 256 std::shared_ptr<AppletMessageQueue> msg_queue;
256 bool vr_mode_state{}; 257 bool vr_mode_state{};
@@ -283,7 +284,7 @@ public:
283 284
284private: 285private:
285 void Register(); 286 void Register();
286 void Open(Kernel::HLERequestContext& ctx); 287 void Open(HLERequestContext& ctx);
287 288
288 std::shared_ptr<IStorageImpl> impl; 289 std::shared_ptr<IStorageImpl> impl;
289}; 290};
@@ -294,9 +295,9 @@ public:
294 ~IStorageAccessor() override; 295 ~IStorageAccessor() override;
295 296
296private: 297private:
297 void GetSize(Kernel::HLERequestContext& ctx); 298 void GetSize(HLERequestContext& ctx);
298 void Write(Kernel::HLERequestContext& ctx); 299 void Write(HLERequestContext& ctx);
299 void Read(Kernel::HLERequestContext& ctx); 300 void Read(HLERequestContext& ctx);
300 301
301 IStorage& backing; 302 IStorage& backing;
302}; 303};
@@ -307,10 +308,10 @@ public:
307 ~ILibraryAppletCreator() override; 308 ~ILibraryAppletCreator() override;
308 309
309private: 310private:
310 void CreateLibraryApplet(Kernel::HLERequestContext& ctx); 311 void CreateLibraryApplet(HLERequestContext& ctx);
311 void CreateStorage(Kernel::HLERequestContext& ctx); 312 void CreateStorage(HLERequestContext& ctx);
312 void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx); 313 void CreateTransferMemoryStorage(HLERequestContext& ctx);
313 void CreateHandleStorage(Kernel::HLERequestContext& ctx); 314 void CreateHandleStorage(HLERequestContext& ctx);
314}; 315};
315 316
316class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { 317class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
@@ -319,39 +320,39 @@ public:
319 ~IApplicationFunctions() override; 320 ~IApplicationFunctions() override;
320 321
321private: 322private:
322 void PopLaunchParameter(Kernel::HLERequestContext& ctx); 323 void PopLaunchParameter(HLERequestContext& ctx);
323 void CreateApplicationAndRequestToStartForQuest(Kernel::HLERequestContext& ctx); 324 void CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx);
324 void EnsureSaveData(Kernel::HLERequestContext& ctx); 325 void EnsureSaveData(HLERequestContext& ctx);
325 void SetTerminateResult(Kernel::HLERequestContext& ctx); 326 void SetTerminateResult(HLERequestContext& ctx);
326 void GetDisplayVersion(Kernel::HLERequestContext& ctx); 327 void GetDisplayVersion(HLERequestContext& ctx);
327 void GetDesiredLanguage(Kernel::HLERequestContext& ctx); 328 void GetDesiredLanguage(HLERequestContext& ctx);
328 void IsGamePlayRecordingSupported(Kernel::HLERequestContext& ctx); 329 void IsGamePlayRecordingSupported(HLERequestContext& ctx);
329 void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx); 330 void InitializeGamePlayRecording(HLERequestContext& ctx);
330 void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx); 331 void SetGamePlayRecordingState(HLERequestContext& ctx);
331 void NotifyRunning(Kernel::HLERequestContext& ctx); 332 void NotifyRunning(HLERequestContext& ctx);
332 void GetPseudoDeviceId(Kernel::HLERequestContext& ctx); 333 void GetPseudoDeviceId(HLERequestContext& ctx);
333 void ExtendSaveData(Kernel::HLERequestContext& ctx); 334 void ExtendSaveData(HLERequestContext& ctx);
334 void GetSaveDataSize(Kernel::HLERequestContext& ctx); 335 void GetSaveDataSize(HLERequestContext& ctx);
335 void BeginBlockingHomeButtonShortAndLongPressed(Kernel::HLERequestContext& ctx); 336 void BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx);
336 void EndBlockingHomeButtonShortAndLongPressed(Kernel::HLERequestContext& ctx); 337 void EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx);
337 void BeginBlockingHomeButton(Kernel::HLERequestContext& ctx); 338 void BeginBlockingHomeButton(HLERequestContext& ctx);
338 void EndBlockingHomeButton(Kernel::HLERequestContext& ctx); 339 void EndBlockingHomeButton(HLERequestContext& ctx);
339 void EnableApplicationCrashReport(Kernel::HLERequestContext& ctx); 340 void EnableApplicationCrashReport(HLERequestContext& ctx);
340 void InitializeApplicationCopyrightFrameBuffer(Kernel::HLERequestContext& ctx); 341 void InitializeApplicationCopyrightFrameBuffer(HLERequestContext& ctx);
341 void SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx); 342 void SetApplicationCopyrightImage(HLERequestContext& ctx);
342 void SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx); 343 void SetApplicationCopyrightVisibility(HLERequestContext& ctx);
343 void QueryApplicationPlayStatistics(Kernel::HLERequestContext& ctx); 344 void QueryApplicationPlayStatistics(HLERequestContext& ctx);
344 void QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx); 345 void QueryApplicationPlayStatisticsByUid(HLERequestContext& ctx);
345 void ExecuteProgram(Kernel::HLERequestContext& ctx); 346 void ExecuteProgram(HLERequestContext& ctx);
346 void ClearUserChannel(Kernel::HLERequestContext& ctx); 347 void ClearUserChannel(HLERequestContext& ctx);
347 void UnpopToUserChannel(Kernel::HLERequestContext& ctx); 348 void UnpopToUserChannel(HLERequestContext& ctx);
348 void GetPreviousProgramIndex(Kernel::HLERequestContext& ctx); 349 void GetPreviousProgramIndex(HLERequestContext& ctx);
349 void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); 350 void GetGpuErrorDetectedSystemEvent(HLERequestContext& ctx);
350 void GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx); 351 void GetFriendInvitationStorageChannelEvent(HLERequestContext& ctx);
351 void TryPopFromFriendInvitationStorageChannel(Kernel::HLERequestContext& ctx); 352 void TryPopFromFriendInvitationStorageChannel(HLERequestContext& ctx);
352 void GetNotificationStorageChannelEvent(Kernel::HLERequestContext& ctx); 353 void GetNotificationStorageChannelEvent(HLERequestContext& ctx);
353 void GetHealthWarningDisappearedSystemEvent(Kernel::HLERequestContext& ctx); 354 void GetHealthWarningDisappearedSystemEvent(HLERequestContext& ctx);
354 void PrepareForJit(Kernel::HLERequestContext& ctx); 355 void PrepareForJit(HLERequestContext& ctx);
355 356
356 KernelHelpers::ServiceContext service_context; 357 KernelHelpers::ServiceContext service_context;
357 358
@@ -370,8 +371,8 @@ public:
370 ~IHomeMenuFunctions() override; 371 ~IHomeMenuFunctions() override;
371 372
372private: 373private:
373 void RequestToGetForeground(Kernel::HLERequestContext& ctx); 374 void RequestToGetForeground(HLERequestContext& ctx);
374 void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx); 375 void GetPopFromGeneralChannelEvent(HLERequestContext& ctx);
375 376
376 KernelHelpers::ServiceContext service_context; 377 KernelHelpers::ServiceContext service_context;
377 378
@@ -396,8 +397,6 @@ public:
396 ~IProcessWindingController() override; 397 ~IProcessWindingController() override;
397}; 398};
398 399
399/// Registers all AM services with the specified service manager. 400void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system);
400void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
401 Core::System& system);
402 401
403} // namespace Service::AM 402} // namespace Service::AM
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp
index d7719da35..2764f7ceb 100644
--- a/src/core/hle/service/am/applet_ae.cpp
+++ b/src/core/hle/service/am/applet_ae.cpp
@@ -3,20 +3,20 @@
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/ipc_helpers.h"
7#include "core/hle/service/am/am.h" 6#include "core/hle/service/am/am.h"
8#include "core/hle/service/am/applet_ae.h" 7#include "core/hle/service/am/applet_ae.h"
9#include "core/hle/service/nvflinger/nvflinger.h" 8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/nvnflinger/nvnflinger.h"
10 10
11namespace Service::AM { 11namespace Service::AM {
12 12
13class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { 13class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
14public: 14public:
15 explicit ILibraryAppletProxy(NVFlinger::NVFlinger& nvflinger_, 15 explicit ILibraryAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_,
16 std::shared_ptr<AppletMessageQueue> msg_queue_, 16 std::shared_ptr<AppletMessageQueue> msg_queue_,
17 Core::System& system_) 17 Core::System& system_)
18 : ServiceFramework{system_, "ILibraryAppletProxy"}, nvflinger{nvflinger_}, 18 : ServiceFramework{system_, "ILibraryAppletProxy"},
19 msg_queue{std::move(msg_queue_)} { 19 nvnflinger{nvnflinger_}, msg_queue{std::move(msg_queue_)} {
20 // clang-format off 20 // clang-format off
21 static const FunctionInfo functions[] = { 21 static const FunctionInfo functions[] = {
22 {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, 22 {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
@@ -36,7 +36,7 @@ public:
36 } 36 }
37 37
38private: 38private:
39 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { 39 void GetCommonStateGetter(HLERequestContext& ctx) {
40 LOG_DEBUG(Service_AM, "called"); 40 LOG_DEBUG(Service_AM, "called");
41 41
42 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 42 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -44,15 +44,15 @@ private:
44 rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue); 44 rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue);
45 } 45 }
46 46
47 void GetSelfController(Kernel::HLERequestContext& ctx) { 47 void GetSelfController(HLERequestContext& ctx) {
48 LOG_DEBUG(Service_AM, "called"); 48 LOG_DEBUG(Service_AM, "called");
49 49
50 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 50 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
51 rb.Push(ResultSuccess); 51 rb.Push(ResultSuccess);
52 rb.PushIpcInterface<ISelfController>(system, nvflinger); 52 rb.PushIpcInterface<ISelfController>(system, nvnflinger);
53 } 53 }
54 54
55 void GetWindowController(Kernel::HLERequestContext& ctx) { 55 void GetWindowController(HLERequestContext& ctx) {
56 LOG_DEBUG(Service_AM, "called"); 56 LOG_DEBUG(Service_AM, "called");
57 57
58 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 58 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -60,7 +60,7 @@ private:
60 rb.PushIpcInterface<IWindowController>(system); 60 rb.PushIpcInterface<IWindowController>(system);
61 } 61 }
62 62
63 void GetAudioController(Kernel::HLERequestContext& ctx) { 63 void GetAudioController(HLERequestContext& ctx) {
64 LOG_DEBUG(Service_AM, "called"); 64 LOG_DEBUG(Service_AM, "called");
65 65
66 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 66 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -68,7 +68,7 @@ private:
68 rb.PushIpcInterface<IAudioController>(system); 68 rb.PushIpcInterface<IAudioController>(system);
69 } 69 }
70 70
71 void GetDisplayController(Kernel::HLERequestContext& ctx) { 71 void GetDisplayController(HLERequestContext& ctx) {
72 LOG_DEBUG(Service_AM, "called"); 72 LOG_DEBUG(Service_AM, "called");
73 73
74 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 74 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -76,7 +76,7 @@ private:
76 rb.PushIpcInterface<IDisplayController>(system); 76 rb.PushIpcInterface<IDisplayController>(system);
77 } 77 }
78 78
79 void GetProcessWindingController(Kernel::HLERequestContext& ctx) { 79 void GetProcessWindingController(HLERequestContext& ctx) {
80 LOG_DEBUG(Service_AM, "called"); 80 LOG_DEBUG(Service_AM, "called");
81 81
82 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 82 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -84,7 +84,7 @@ private:
84 rb.PushIpcInterface<IProcessWindingController>(system); 84 rb.PushIpcInterface<IProcessWindingController>(system);
85 } 85 }
86 86
87 void GetDebugFunctions(Kernel::HLERequestContext& ctx) { 87 void GetDebugFunctions(HLERequestContext& ctx) {
88 LOG_DEBUG(Service_AM, "called"); 88 LOG_DEBUG(Service_AM, "called");
89 89
90 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 90 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -92,7 +92,7 @@ private:
92 rb.PushIpcInterface<IDebugFunctions>(system); 92 rb.PushIpcInterface<IDebugFunctions>(system);
93 } 93 }
94 94
95 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { 95 void GetLibraryAppletCreator(HLERequestContext& ctx) {
96 LOG_DEBUG(Service_AM, "called"); 96 LOG_DEBUG(Service_AM, "called");
97 97
98 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 98 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -100,7 +100,7 @@ private:
100 rb.PushIpcInterface<ILibraryAppletCreator>(system); 100 rb.PushIpcInterface<ILibraryAppletCreator>(system);
101 } 101 }
102 102
103 void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { 103 void GetApplicationFunctions(HLERequestContext& ctx) {
104 LOG_DEBUG(Service_AM, "called"); 104 LOG_DEBUG(Service_AM, "called");
105 105
106 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 106 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -108,17 +108,17 @@ private:
108 rb.PushIpcInterface<IApplicationFunctions>(system); 108 rb.PushIpcInterface<IApplicationFunctions>(system);
109 } 109 }
110 110
111 NVFlinger::NVFlinger& nvflinger; 111 Nvnflinger::Nvnflinger& nvnflinger;
112 std::shared_ptr<AppletMessageQueue> msg_queue; 112 std::shared_ptr<AppletMessageQueue> msg_queue;
113}; 113};
114 114
115class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { 115class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
116public: 116public:
117 explicit ISystemAppletProxy(NVFlinger::NVFlinger& nvflinger_, 117 explicit ISystemAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_,
118 std::shared_ptr<AppletMessageQueue> msg_queue_, 118 std::shared_ptr<AppletMessageQueue> msg_queue_,
119 Core::System& system_) 119 Core::System& system_)
120 : ServiceFramework{system_, "ISystemAppletProxy"}, nvflinger{nvflinger_}, 120 : ServiceFramework{system_, "ISystemAppletProxy"},
121 msg_queue{std::move(msg_queue_)} { 121 nvnflinger{nvnflinger_}, msg_queue{std::move(msg_queue_)} {
122 // clang-format off 122 // clang-format off
123 static const FunctionInfo functions[] = { 123 static const FunctionInfo functions[] = {
124 {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, 124 {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
@@ -140,7 +140,7 @@ public:
140 } 140 }
141 141
142private: 142private:
143 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { 143 void GetCommonStateGetter(HLERequestContext& ctx) {
144 LOG_DEBUG(Service_AM, "called"); 144 LOG_DEBUG(Service_AM, "called");
145 145
146 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 146 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -148,15 +148,15 @@ private:
148 rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue); 148 rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue);
149 } 149 }
150 150
151 void GetSelfController(Kernel::HLERequestContext& ctx) { 151 void GetSelfController(HLERequestContext& ctx) {
152 LOG_DEBUG(Service_AM, "called"); 152 LOG_DEBUG(Service_AM, "called");
153 153
154 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 154 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
155 rb.Push(ResultSuccess); 155 rb.Push(ResultSuccess);
156 rb.PushIpcInterface<ISelfController>(system, nvflinger); 156 rb.PushIpcInterface<ISelfController>(system, nvnflinger);
157 } 157 }
158 158
159 void GetWindowController(Kernel::HLERequestContext& ctx) { 159 void GetWindowController(HLERequestContext& ctx) {
160 LOG_DEBUG(Service_AM, "called"); 160 LOG_DEBUG(Service_AM, "called");
161 161
162 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 162 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -164,7 +164,7 @@ private:
164 rb.PushIpcInterface<IWindowController>(system); 164 rb.PushIpcInterface<IWindowController>(system);
165 } 165 }
166 166
167 void GetAudioController(Kernel::HLERequestContext& ctx) { 167 void GetAudioController(HLERequestContext& ctx) {
168 LOG_DEBUG(Service_AM, "called"); 168 LOG_DEBUG(Service_AM, "called");
169 169
170 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 170 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -172,7 +172,7 @@ private:
172 rb.PushIpcInterface<IAudioController>(system); 172 rb.PushIpcInterface<IAudioController>(system);
173 } 173 }
174 174
175 void GetDisplayController(Kernel::HLERequestContext& ctx) { 175 void GetDisplayController(HLERequestContext& ctx) {
176 LOG_DEBUG(Service_AM, "called"); 176 LOG_DEBUG(Service_AM, "called");
177 177
178 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 178 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -180,7 +180,7 @@ private:
180 rb.PushIpcInterface<IDisplayController>(system); 180 rb.PushIpcInterface<IDisplayController>(system);
181 } 181 }
182 182
183 void GetDebugFunctions(Kernel::HLERequestContext& ctx) { 183 void GetDebugFunctions(HLERequestContext& ctx) {
184 LOG_DEBUG(Service_AM, "called"); 184 LOG_DEBUG(Service_AM, "called");
185 185
186 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 186 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -188,7 +188,7 @@ private:
188 rb.PushIpcInterface<IDebugFunctions>(system); 188 rb.PushIpcInterface<IDebugFunctions>(system);
189 } 189 }
190 190
191 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { 191 void GetLibraryAppletCreator(HLERequestContext& ctx) {
192 LOG_DEBUG(Service_AM, "called"); 192 LOG_DEBUG(Service_AM, "called");
193 193
194 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 194 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -196,7 +196,7 @@ private:
196 rb.PushIpcInterface<ILibraryAppletCreator>(system); 196 rb.PushIpcInterface<ILibraryAppletCreator>(system);
197 } 197 }
198 198
199 void GetHomeMenuFunctions(Kernel::HLERequestContext& ctx) { 199 void GetHomeMenuFunctions(HLERequestContext& ctx) {
200 LOG_DEBUG(Service_AM, "called"); 200 LOG_DEBUG(Service_AM, "called");
201 201
202 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 202 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -204,7 +204,7 @@ private:
204 rb.PushIpcInterface<IHomeMenuFunctions>(system); 204 rb.PushIpcInterface<IHomeMenuFunctions>(system);
205 } 205 }
206 206
207 void GetGlobalStateController(Kernel::HLERequestContext& ctx) { 207 void GetGlobalStateController(HLERequestContext& ctx) {
208 LOG_DEBUG(Service_AM, "called"); 208 LOG_DEBUG(Service_AM, "called");
209 209
210 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 210 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -212,7 +212,7 @@ private:
212 rb.PushIpcInterface<IGlobalStateController>(system); 212 rb.PushIpcInterface<IGlobalStateController>(system);
213 } 213 }
214 214
215 void GetApplicationCreator(Kernel::HLERequestContext& ctx) { 215 void GetApplicationCreator(HLERequestContext& ctx) {
216 LOG_DEBUG(Service_AM, "called"); 216 LOG_DEBUG(Service_AM, "called");
217 217
218 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 218 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -220,38 +220,38 @@ private:
220 rb.PushIpcInterface<IApplicationCreator>(system); 220 rb.PushIpcInterface<IApplicationCreator>(system);
221 } 221 }
222 222
223 NVFlinger::NVFlinger& nvflinger; 223 Nvnflinger::Nvnflinger& nvnflinger;
224 std::shared_ptr<AppletMessageQueue> msg_queue; 224 std::shared_ptr<AppletMessageQueue> msg_queue;
225}; 225};
226 226
227void AppletAE::OpenSystemAppletProxy(Kernel::HLERequestContext& ctx) { 227void AppletAE::OpenSystemAppletProxy(HLERequestContext& ctx) {
228 LOG_DEBUG(Service_AM, "called"); 228 LOG_DEBUG(Service_AM, "called");
229 229
230 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 230 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
231 rb.Push(ResultSuccess); 231 rb.Push(ResultSuccess);
232 rb.PushIpcInterface<ISystemAppletProxy>(nvflinger, msg_queue, system); 232 rb.PushIpcInterface<ISystemAppletProxy>(nvnflinger, msg_queue, system);
233} 233}
234 234
235void AppletAE::OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx) { 235void AppletAE::OpenLibraryAppletProxy(HLERequestContext& ctx) {
236 LOG_DEBUG(Service_AM, "called"); 236 LOG_DEBUG(Service_AM, "called");
237 237
238 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 238 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
239 rb.Push(ResultSuccess); 239 rb.Push(ResultSuccess);
240 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue, system); 240 rb.PushIpcInterface<ILibraryAppletProxy>(nvnflinger, msg_queue, system);
241} 241}
242 242
243void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) { 243void AppletAE::OpenLibraryAppletProxyOld(HLERequestContext& ctx) {
244 LOG_DEBUG(Service_AM, "called"); 244 LOG_DEBUG(Service_AM, "called");
245 245
246 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 246 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
247 rb.Push(ResultSuccess); 247 rb.Push(ResultSuccess);
248 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue, system); 248 rb.PushIpcInterface<ILibraryAppletProxy>(nvnflinger, msg_queue, system);
249} 249}
250 250
251AppletAE::AppletAE(NVFlinger::NVFlinger& nvflinger_, std::shared_ptr<AppletMessageQueue> msg_queue_, 251AppletAE::AppletAE(Nvnflinger::Nvnflinger& nvnflinger_,
252 Core::System& system_) 252 std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_)
253 : ServiceFramework{system_, "appletAE"}, nvflinger{nvflinger_}, msg_queue{ 253 : ServiceFramework{system_, "appletAE"}, nvnflinger{nvnflinger_}, msg_queue{
254 std::move(msg_queue_)} { 254 std::move(msg_queue_)} {
255 // clang-format off 255 // clang-format off
256 static const FunctionInfo functions[] = { 256 static const FunctionInfo functions[] = {
257 {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"}, 257 {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"},
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h
index 2147976a6..538ce2903 100644
--- a/src/core/hle/service/am/applet_ae.h
+++ b/src/core/hle/service/am/applet_ae.h
@@ -12,8 +12,8 @@ namespace FileSystem {
12class FileSystemController; 12class FileSystemController;
13} 13}
14 14
15namespace NVFlinger { 15namespace Nvnflinger {
16class NVFlinger; 16class Nvnflinger;
17} 17}
18 18
19namespace AM { 19namespace AM {
@@ -22,18 +22,18 @@ class AppletMessageQueue;
22 22
23class AppletAE final : public ServiceFramework<AppletAE> { 23class AppletAE final : public ServiceFramework<AppletAE> {
24public: 24public:
25 explicit AppletAE(NVFlinger::NVFlinger& nvflinger_, 25 explicit AppletAE(Nvnflinger::Nvnflinger& nvnflinger_,
26 std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_); 26 std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_);
27 ~AppletAE() override; 27 ~AppletAE() override;
28 28
29 const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const; 29 const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
30 30
31private: 31private:
32 void OpenSystemAppletProxy(Kernel::HLERequestContext& ctx); 32 void OpenSystemAppletProxy(HLERequestContext& ctx);
33 void OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx); 33 void OpenLibraryAppletProxy(HLERequestContext& ctx);
34 void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx); 34 void OpenLibraryAppletProxyOld(HLERequestContext& ctx);
35 35
36 NVFlinger::NVFlinger& nvflinger; 36 Nvnflinger::Nvnflinger& nvnflinger;
37 std::shared_ptr<AppletMessageQueue> msg_queue; 37 std::shared_ptr<AppletMessageQueue> msg_queue;
38}; 38};
39 39
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp
index 00fc4202c..d6c565d85 100644
--- a/src/core/hle/service/am/applet_oe.cpp
+++ b/src/core/hle/service/am/applet_oe.cpp
@@ -2,20 +2,20 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/am/am.h" 5#include "core/hle/service/am/am.h"
7#include "core/hle/service/am/applet_oe.h" 6#include "core/hle/service/am/applet_oe.h"
8#include "core/hle/service/nvflinger/nvflinger.h" 7#include "core/hle/service/ipc_helpers.h"
8#include "core/hle/service/nvnflinger/nvnflinger.h"
9 9
10namespace Service::AM { 10namespace Service::AM {
11 11
12class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { 12class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
13public: 13public:
14 explicit IApplicationProxy(NVFlinger::NVFlinger& nvflinger_, 14 explicit IApplicationProxy(Nvnflinger::Nvnflinger& nvnflinger_,
15 std::shared_ptr<AppletMessageQueue> msg_queue_, 15 std::shared_ptr<AppletMessageQueue> msg_queue_,
16 Core::System& system_) 16 Core::System& system_)
17 : ServiceFramework{system_, "IApplicationProxy"}, nvflinger{nvflinger_}, 17 : ServiceFramework{system_, "IApplicationProxy"},
18 msg_queue{std::move(msg_queue_)} { 18 nvnflinger{nvnflinger_}, msg_queue{std::move(msg_queue_)} {
19 // clang-format off 19 // clang-format off
20 static const FunctionInfo functions[] = { 20 static const FunctionInfo functions[] = {
21 {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"}, 21 {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"},
@@ -34,7 +34,7 @@ public:
34 } 34 }
35 35
36private: 36private:
37 void GetAudioController(Kernel::HLERequestContext& ctx) { 37 void GetAudioController(HLERequestContext& ctx) {
38 LOG_DEBUG(Service_AM, "called"); 38 LOG_DEBUG(Service_AM, "called");
39 39
40 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 40 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -42,7 +42,7 @@ private:
42 rb.PushIpcInterface<IAudioController>(system); 42 rb.PushIpcInterface<IAudioController>(system);
43 } 43 }
44 44
45 void GetDisplayController(Kernel::HLERequestContext& ctx) { 45 void GetDisplayController(HLERequestContext& ctx) {
46 LOG_DEBUG(Service_AM, "called"); 46 LOG_DEBUG(Service_AM, "called");
47 47
48 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 48 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -50,7 +50,7 @@ private:
50 rb.PushIpcInterface<IDisplayController>(system); 50 rb.PushIpcInterface<IDisplayController>(system);
51 } 51 }
52 52
53 void GetDebugFunctions(Kernel::HLERequestContext& ctx) { 53 void GetDebugFunctions(HLERequestContext& ctx) {
54 LOG_DEBUG(Service_AM, "called"); 54 LOG_DEBUG(Service_AM, "called");
55 55
56 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 56 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -58,7 +58,7 @@ private:
58 rb.PushIpcInterface<IDebugFunctions>(system); 58 rb.PushIpcInterface<IDebugFunctions>(system);
59 } 59 }
60 60
61 void GetWindowController(Kernel::HLERequestContext& ctx) { 61 void GetWindowController(HLERequestContext& ctx) {
62 LOG_DEBUG(Service_AM, "called"); 62 LOG_DEBUG(Service_AM, "called");
63 63
64 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 64 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -66,15 +66,15 @@ private:
66 rb.PushIpcInterface<IWindowController>(system); 66 rb.PushIpcInterface<IWindowController>(system);
67 } 67 }
68 68
69 void GetSelfController(Kernel::HLERequestContext& ctx) { 69 void GetSelfController(HLERequestContext& ctx) {
70 LOG_DEBUG(Service_AM, "called"); 70 LOG_DEBUG(Service_AM, "called");
71 71
72 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 72 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
73 rb.Push(ResultSuccess); 73 rb.Push(ResultSuccess);
74 rb.PushIpcInterface<ISelfController>(system, nvflinger); 74 rb.PushIpcInterface<ISelfController>(system, nvnflinger);
75 } 75 }
76 76
77 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { 77 void GetCommonStateGetter(HLERequestContext& ctx) {
78 LOG_DEBUG(Service_AM, "called"); 78 LOG_DEBUG(Service_AM, "called");
79 79
80 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 80 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -82,7 +82,7 @@ private:
82 rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue); 82 rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue);
83 } 83 }
84 84
85 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { 85 void GetLibraryAppletCreator(HLERequestContext& ctx) {
86 LOG_DEBUG(Service_AM, "called"); 86 LOG_DEBUG(Service_AM, "called");
87 87
88 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 88 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -90,7 +90,7 @@ private:
90 rb.PushIpcInterface<ILibraryAppletCreator>(system); 90 rb.PushIpcInterface<ILibraryAppletCreator>(system);
91 } 91 }
92 92
93 void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { 93 void GetApplicationFunctions(HLERequestContext& ctx) {
94 LOG_DEBUG(Service_AM, "called"); 94 LOG_DEBUG(Service_AM, "called");
95 95
96 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 96 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -98,22 +98,22 @@ private:
98 rb.PushIpcInterface<IApplicationFunctions>(system); 98 rb.PushIpcInterface<IApplicationFunctions>(system);
99 } 99 }
100 100
101 NVFlinger::NVFlinger& nvflinger; 101 Nvnflinger::Nvnflinger& nvnflinger;
102 std::shared_ptr<AppletMessageQueue> msg_queue; 102 std::shared_ptr<AppletMessageQueue> msg_queue;
103}; 103};
104 104
105void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) { 105void AppletOE::OpenApplicationProxy(HLERequestContext& ctx) {
106 LOG_DEBUG(Service_AM, "called"); 106 LOG_DEBUG(Service_AM, "called");
107 107
108 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 108 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
109 rb.Push(ResultSuccess); 109 rb.Push(ResultSuccess);
110 rb.PushIpcInterface<IApplicationProxy>(nvflinger, msg_queue, system); 110 rb.PushIpcInterface<IApplicationProxy>(nvnflinger, msg_queue, system);
111} 111}
112 112
113AppletOE::AppletOE(NVFlinger::NVFlinger& nvflinger_, std::shared_ptr<AppletMessageQueue> msg_queue_, 113AppletOE::AppletOE(Nvnflinger::Nvnflinger& nvnflinger_,
114 Core::System& system_) 114 std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_)
115 : ServiceFramework{system_, "appletOE"}, nvflinger{nvflinger_}, msg_queue{ 115 : ServiceFramework{system_, "appletOE"}, nvnflinger{nvnflinger_}, msg_queue{
116 std::move(msg_queue_)} { 116 std::move(msg_queue_)} {
117 static const FunctionInfo functions[] = { 117 static const FunctionInfo functions[] = {
118 {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"}, 118 {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"},
119 }; 119 };
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h
index 8fea249f1..39eccc4ab 100644
--- a/src/core/hle/service/am/applet_oe.h
+++ b/src/core/hle/service/am/applet_oe.h
@@ -12,8 +12,8 @@ namespace FileSystem {
12class FileSystemController; 12class FileSystemController;
13} 13}
14 14
15namespace NVFlinger { 15namespace Nvnflinger {
16class NVFlinger; 16class Nvnflinger;
17} 17}
18 18
19namespace AM { 19namespace AM {
@@ -22,16 +22,16 @@ class AppletMessageQueue;
22 22
23class AppletOE final : public ServiceFramework<AppletOE> { 23class AppletOE final : public ServiceFramework<AppletOE> {
24public: 24public:
25 explicit AppletOE(NVFlinger::NVFlinger& nvflinger_, 25 explicit AppletOE(Nvnflinger::Nvnflinger& nvnflinger_,
26 std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_); 26 std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_);
27 ~AppletOE() override; 27 ~AppletOE() override;
28 28
29 const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const; 29 const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
30 30
31private: 31private:
32 void OpenApplicationProxy(Kernel::HLERequestContext& ctx); 32 void OpenApplicationProxy(HLERequestContext& ctx);
33 33
34 NVFlinger::NVFlinger& nvflinger; 34 Nvnflinger::Nvnflinger& nvnflinger;
35 std::shared_ptr<AppletMessageQueue> msg_queue; 35 std::shared_ptr<AppletMessageQueue> msg_queue;
36}; 36};
37 37
diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp
index b418031de..58484519b 100644
--- a/src/core/hle/service/am/applets/applet_controller.cpp
+++ b/src/core/hle/service/am/applets/applet_controller.cpp
@@ -19,10 +19,9 @@
19 19
20namespace Service::AM::Applets { 20namespace Service::AM::Applets {
21 21
22// This error code (0x183ACA) is thrown when the applet fails to initialize. 22[[maybe_unused]] constexpr Result ResultControllerSupportCanceled{ErrorModule::HID, 3101};
23[[maybe_unused]] constexpr Result ERR_CONTROLLER_APPLET_3101{ErrorModule::HID, 3101}; 23[[maybe_unused]] constexpr Result ResultControllerSupportNotSupportedNpadStyle{ErrorModule::HID,
24// This error code (0x183CCA) is thrown when the u32 result in ControllerSupportResultInfo is 2. 24 3102};
25[[maybe_unused]] constexpr Result ERR_CONTROLLER_APPLET_3102{ErrorModule::HID, 3102};
26 25
27static Core::Frontend::ControllerParameters ConvertToFrontendParameters( 26static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
28 ControllerSupportArgPrivate private_arg, ControllerSupportArgHeader header, bool enable_text, 27 ControllerSupportArgPrivate private_arg, ControllerSupportArgHeader header, bool enable_text,
diff --git a/src/core/hle/service/am/applets/applet_profile_select.cpp b/src/core/hle/service/am/applets/applet_profile_select.cpp
index c738db028..1d69f5447 100644
--- a/src/core/hle/service/am/applets/applet_profile_select.cpp
+++ b/src/core/hle/service/am/applets/applet_profile_select.cpp
@@ -7,13 +7,12 @@
7#include "common/string_util.h" 7#include "common/string_util.h"
8#include "core/core.h" 8#include "core/core.h"
9#include "core/frontend/applets/profile_select.h" 9#include "core/frontend/applets/profile_select.h"
10#include "core/hle/service/acc/errors.h"
10#include "core/hle/service/am/am.h" 11#include "core/hle/service/am/am.h"
11#include "core/hle/service/am/applets/applet_profile_select.h" 12#include "core/hle/service/am/applets/applet_profile_select.h"
12 13
13namespace Service::AM::Applets { 14namespace Service::AM::Applets {
14 15
15constexpr Result ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1};
16
17ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, 16ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
18 const Core::Frontend::ProfileSelectApplet& frontend_) 17 const Core::Frontend::ProfileSelectApplet& frontend_)
19 : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} 18 : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
@@ -63,8 +62,8 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
63 output.result = 0; 62 output.result = 0;
64 output.uuid_selected = *uuid; 63 output.uuid_selected = *uuid;
65 } else { 64 } else {
66 status = ERR_USER_CANCELLED_SELECTION; 65 status = Account::ResultCancelledByUser;
67 output.result = ERR_USER_CANCELLED_SELECTION.raw; 66 output.result = Account::ResultCancelledByUser.raw;
68 output.uuid_selected = Common::InvalidUUID; 67 output.uuid_selected = Common::InvalidUUID;
69 } 68 }
70 69
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index 1bbf057cb..38c2138e8 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -14,9 +14,10 @@
14#include "core/file_sys/nca_metadata.h" 14#include "core/file_sys/nca_metadata.h"
15#include "core/file_sys/patch_manager.h" 15#include "core/file_sys/patch_manager.h"
16#include "core/file_sys/registered_cache.h" 16#include "core/file_sys/registered_cache.h"
17#include "core/hle/ipc_helpers.h"
18#include "core/hle/kernel/k_event.h" 17#include "core/hle/kernel/k_event.h"
19#include "core/hle/service/aoc/aoc_u.h" 18#include "core/hle/service/aoc/aoc_u.h"
19#include "core/hle/service/ipc_helpers.h"
20#include "core/hle/service/server_manager.h"
20#include "core/loader/loader.h" 21#include "core/loader/loader.h"
21 22
22namespace Service::AOC { 23namespace Service::AOC {
@@ -68,7 +69,7 @@ public:
68 } 69 }
69 70
70private: 71private:
71 void SetDefaultDeliveryTarget(Kernel::HLERequestContext& ctx) { 72 void SetDefaultDeliveryTarget(HLERequestContext& ctx) {
72 IPC::RequestParser rp{ctx}; 73 IPC::RequestParser rp{ctx};
73 74
74 const auto unknown_1 = rp.Pop<u64>(); 75 const auto unknown_1 = rp.Pop<u64>();
@@ -80,7 +81,7 @@ private:
80 rb.Push(ResultSuccess); 81 rb.Push(ResultSuccess);
81 } 82 }
82 83
83 void SetDeliveryTarget(Kernel::HLERequestContext& ctx) { 84 void SetDeliveryTarget(HLERequestContext& ctx) {
84 IPC::RequestParser rp{ctx}; 85 IPC::RequestParser rp{ctx};
85 86
86 const auto unknown_1 = rp.Pop<u64>(); 87 const auto unknown_1 = rp.Pop<u64>();
@@ -92,7 +93,7 @@ private:
92 rb.Push(ResultSuccess); 93 rb.Push(ResultSuccess);
93 } 94 }
94 95
95 void GetPurchasedEventReadableHandle(Kernel::HLERequestContext& ctx) { 96 void GetPurchasedEventReadableHandle(HLERequestContext& ctx) {
96 LOG_WARNING(Service_AOC, "called"); 97 LOG_WARNING(Service_AOC, "called");
97 98
98 IPC::ResponseBuilder rb{ctx, 2, 1}; 99 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -144,7 +145,7 @@ AOC_U::~AOC_U() {
144 service_context.CloseEvent(aoc_change_event); 145 service_context.CloseEvent(aoc_change_event);
145} 146}
146 147
147void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) { 148void AOC_U::CountAddOnContent(HLERequestContext& ctx) {
148 struct Parameters { 149 struct Parameters {
149 u64 process_id; 150 u64 process_id;
150 }; 151 };
@@ -171,7 +172,7 @@ void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) {
171 [current](u64 tid) { return CheckAOCTitleIDMatchesBase(tid, current); }))); 172 [current](u64 tid) { return CheckAOCTitleIDMatchesBase(tid, current); })));
172} 173}
173 174
174void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) { 175void AOC_U::ListAddOnContent(HLERequestContext& ctx) {
175 struct Parameters { 176 struct Parameters {
176 u32 offset; 177 u32 offset;
177 u32 count; 178 u32 count;
@@ -217,7 +218,7 @@ void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) {
217 rb.Push(out_count); 218 rb.Push(out_count);
218} 219}
219 220
220void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) { 221void AOC_U::GetAddOnContentBaseId(HLERequestContext& ctx) {
221 struct Parameters { 222 struct Parameters {
222 u64 process_id; 223 u64 process_id;
223 }; 224 };
@@ -244,7 +245,7 @@ void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) {
244 rb.Push(res.first->GetDLCBaseTitleId()); 245 rb.Push(res.first->GetDLCBaseTitleId());
245} 246}
246 247
247void AOC_U::PrepareAddOnContent(Kernel::HLERequestContext& ctx) { 248void AOC_U::PrepareAddOnContent(HLERequestContext& ctx) {
248 struct Parameters { 249 struct Parameters {
249 s32 addon_index; 250 s32 addon_index;
250 u64 process_id; 251 u64 process_id;
@@ -261,7 +262,7 @@ void AOC_U::PrepareAddOnContent(Kernel::HLERequestContext& ctx) {
261 rb.Push(ResultSuccess); 262 rb.Push(ResultSuccess);
262} 263}
263 264
264void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) { 265void AOC_U::GetAddOnContentListChangedEvent(HLERequestContext& ctx) {
265 LOG_WARNING(Service_AOC, "(STUBBED) called"); 266 LOG_WARNING(Service_AOC, "(STUBBED) called");
266 267
267 IPC::ResponseBuilder rb{ctx, 2, 1}; 268 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -269,7 +270,7 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) {
269 rb.PushCopyObjects(aoc_change_event->GetReadableEvent()); 270 rb.PushCopyObjects(aoc_change_event->GetReadableEvent());
270} 271}
271 272
272void AOC_U::GetAddOnContentListChangedEventWithProcessId(Kernel::HLERequestContext& ctx) { 273void AOC_U::GetAddOnContentListChangedEventWithProcessId(HLERequestContext& ctx) {
273 LOG_WARNING(Service_AOC, "(STUBBED) called"); 274 LOG_WARNING(Service_AOC, "(STUBBED) called");
274 275
275 IPC::ResponseBuilder rb{ctx, 2, 1}; 276 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -277,28 +278,28 @@ void AOC_U::GetAddOnContentListChangedEventWithProcessId(Kernel::HLERequestConte
277 rb.PushCopyObjects(aoc_change_event->GetReadableEvent()); 278 rb.PushCopyObjects(aoc_change_event->GetReadableEvent());
278} 279}
279 280
280void AOC_U::NotifyMountAddOnContent(Kernel::HLERequestContext& ctx) { 281void AOC_U::NotifyMountAddOnContent(HLERequestContext& ctx) {
281 LOG_WARNING(Service_AOC, "(STUBBED) called"); 282 LOG_WARNING(Service_AOC, "(STUBBED) called");
282 283
283 IPC::ResponseBuilder rb{ctx, 2}; 284 IPC::ResponseBuilder rb{ctx, 2};
284 rb.Push(ResultSuccess); 285 rb.Push(ResultSuccess);
285} 286}
286 287
287void AOC_U::NotifyUnmountAddOnContent(Kernel::HLERequestContext& ctx) { 288void AOC_U::NotifyUnmountAddOnContent(HLERequestContext& ctx) {
288 LOG_WARNING(Service_AOC, "(STUBBED) called"); 289 LOG_WARNING(Service_AOC, "(STUBBED) called");
289 290
290 IPC::ResponseBuilder rb{ctx, 2}; 291 IPC::ResponseBuilder rb{ctx, 2};
291 rb.Push(ResultSuccess); 292 rb.Push(ResultSuccess);
292} 293}
293 294
294void AOC_U::CheckAddOnContentMountStatus(Kernel::HLERequestContext& ctx) { 295void AOC_U::CheckAddOnContentMountStatus(HLERequestContext& ctx) {
295 LOG_WARNING(Service_AOC, "(STUBBED) called"); 296 LOG_WARNING(Service_AOC, "(STUBBED) called");
296 297
297 IPC::ResponseBuilder rb{ctx, 2}; 298 IPC::ResponseBuilder rb{ctx, 2};
298 rb.Push(ResultSuccess); 299 rb.Push(ResultSuccess);
299} 300}
300 301
301void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) { 302void AOC_U::CreateEcPurchasedEventManager(HLERequestContext& ctx) {
302 LOG_WARNING(Service_AOC, "(STUBBED) called"); 303 LOG_WARNING(Service_AOC, "(STUBBED) called");
303 304
304 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 305 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -306,7 +307,7 @@ void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) {
306 rb.PushIpcInterface<IPurchaseEventManager>(system); 307 rb.PushIpcInterface<IPurchaseEventManager>(system);
307} 308}
308 309
309void AOC_U::CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx) { 310void AOC_U::CreatePermanentEcPurchasedEventManager(HLERequestContext& ctx) {
310 LOG_WARNING(Service_AOC, "(STUBBED) called"); 311 LOG_WARNING(Service_AOC, "(STUBBED) called");
311 312
312 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 313 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -314,8 +315,10 @@ void AOC_U::CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ct
314 rb.PushIpcInterface<IPurchaseEventManager>(system); 315 rb.PushIpcInterface<IPurchaseEventManager>(system);
315} 316}
316 317
317void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 318void LoopProcess(Core::System& system) {
318 std::make_shared<AOC_U>(system)->InstallAsService(service_manager); 319 auto server_manager = std::make_unique<ServerManager>(system);
320 server_manager->RegisterNamedService("aoc:u", std::make_shared<AOC_U>(system));
321 ServerManager::RunServer(std::move(server_manager));
319} 322}
320 323
321} // namespace Service::AOC 324} // namespace Service::AOC
diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h
index 6c1ce601a..12ccfeb6a 100644
--- a/src/core/hle/service/aoc/aoc_u.h
+++ b/src/core/hle/service/aoc/aoc_u.h
@@ -22,17 +22,17 @@ public:
22 ~AOC_U() override; 22 ~AOC_U() override;
23 23
24private: 24private:
25 void CountAddOnContent(Kernel::HLERequestContext& ctx); 25 void CountAddOnContent(HLERequestContext& ctx);
26 void ListAddOnContent(Kernel::HLERequestContext& ctx); 26 void ListAddOnContent(HLERequestContext& ctx);
27 void GetAddOnContentBaseId(Kernel::HLERequestContext& ctx); 27 void GetAddOnContentBaseId(HLERequestContext& ctx);
28 void PrepareAddOnContent(Kernel::HLERequestContext& ctx); 28 void PrepareAddOnContent(HLERequestContext& ctx);
29 void GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx); 29 void GetAddOnContentListChangedEvent(HLERequestContext& ctx);
30 void GetAddOnContentListChangedEventWithProcessId(Kernel::HLERequestContext& ctx); 30 void GetAddOnContentListChangedEventWithProcessId(HLERequestContext& ctx);
31 void NotifyMountAddOnContent(Kernel::HLERequestContext& ctx); 31 void NotifyMountAddOnContent(HLERequestContext& ctx);
32 void NotifyUnmountAddOnContent(Kernel::HLERequestContext& ctx); 32 void NotifyUnmountAddOnContent(HLERequestContext& ctx);
33 void CheckAddOnContentMountStatus(Kernel::HLERequestContext& ctx); 33 void CheckAddOnContentMountStatus(HLERequestContext& ctx);
34 void CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx); 34 void CreateEcPurchasedEventManager(HLERequestContext& ctx);
35 void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx); 35 void CreatePermanentEcPurchasedEventManager(HLERequestContext& ctx);
36 36
37 std::vector<u64> add_on_content; 37 std::vector<u64> add_on_content;
38 KernelHelpers::ServiceContext service_context; 38 KernelHelpers::ServiceContext service_context;
@@ -40,7 +40,6 @@ private:
40 Kernel::KEvent* aoc_change_event; 40 Kernel::KEvent* aoc_change_event;
41}; 41};
42 42
43/// Registers all AOC services with the specified service manager. 43void LoopProcess(Core::System& system);
44void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
45 44
46} // namespace Service::AOC 45} // namespace Service::AOC
diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp
index 44b2927a6..c23ff293d 100644
--- a/src/core/hle/service/apm/apm.cpp
+++ b/src/core/hle/service/apm/apm.cpp
@@ -4,20 +4,24 @@
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hle/service/apm/apm.h" 5#include "core/hle/service/apm/apm.h"
6#include "core/hle/service/apm/apm_interface.h" 6#include "core/hle/service/apm/apm_interface.h"
7#include "core/hle/service/server_manager.h"
7 8
8namespace Service::APM { 9namespace Service::APM {
9 10
10Module::Module() = default; 11Module::Module() = default;
11Module::~Module() = default; 12Module::~Module() = default;
12 13
13void InstallInterfaces(Core::System& system) { 14void LoopProcess(Core::System& system) {
14 auto module_ = std::make_shared<Module>(); 15 auto module = std::make_shared<Module>();
15 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm") 16 auto server_manager = std::make_unique<ServerManager>(system);
16 ->InstallAsService(system.ServiceManager()); 17
17 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm:am") 18 server_manager->RegisterNamedService(
18 ->InstallAsService(system.ServiceManager()); 19 "apm", std::make_shared<APM>(system, module, system.GetAPMController(), "apm"));
19 std::make_shared<APM_Sys>(system, system.GetAPMController()) 20 server_manager->RegisterNamedService(
20 ->InstallAsService(system.ServiceManager()); 21 "apm:am", std::make_shared<APM>(system, module, system.GetAPMController(), "apm:am"));
22 server_manager->RegisterNamedService(
23 "apm:sys", std::make_shared<APM_Sys>(system, system.GetAPMController()));
24 ServerManager::RunServer(std::move(server_manager));
21} 25}
22 26
23} // namespace Service::APM 27} // namespace Service::APM
diff --git a/src/core/hle/service/apm/apm.h b/src/core/hle/service/apm/apm.h
index 0fecc766a..e188b4e44 100644
--- a/src/core/hle/service/apm/apm.h
+++ b/src/core/hle/service/apm/apm.h
@@ -15,7 +15,6 @@ public:
15 ~Module(); 15 ~Module();
16}; 16};
17 17
18/// Registers all AM services with the specified service manager. 18void LoopProcess(Core::System& system);
19void InstallInterfaces(Core::System& system);
20 19
21} // namespace Service::APM 20} // namespace Service::APM
diff --git a/src/core/hle/service/apm/apm_interface.cpp b/src/core/hle/service/apm/apm_interface.cpp
index 041fc16bd..d29051ee7 100644
--- a/src/core/hle/service/apm/apm_interface.cpp
+++ b/src/core/hle/service/apm/apm_interface.cpp
@@ -2,10 +2,10 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/apm/apm.h" 5#include "core/hle/service/apm/apm.h"
7#include "core/hle/service/apm/apm_controller.h" 6#include "core/hle/service/apm/apm_controller.h"
8#include "core/hle/service/apm/apm_interface.h" 7#include "core/hle/service/apm/apm_interface.h"
8#include "core/hle/service/ipc_helpers.h"
9 9
10namespace Service::APM { 10namespace Service::APM {
11 11
@@ -22,7 +22,7 @@ public:
22 } 22 }
23 23
24private: 24private:
25 void SetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { 25 void SetPerformanceConfiguration(HLERequestContext& ctx) {
26 IPC::RequestParser rp{ctx}; 26 IPC::RequestParser rp{ctx};
27 27
28 const auto mode = rp.PopEnum<PerformanceMode>(); 28 const auto mode = rp.PopEnum<PerformanceMode>();
@@ -35,7 +35,7 @@ private:
35 rb.Push(ResultSuccess); 35 rb.Push(ResultSuccess);
36 } 36 }
37 37
38 void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { 38 void GetPerformanceConfiguration(HLERequestContext& ctx) {
39 IPC::RequestParser rp{ctx}; 39 IPC::RequestParser rp{ctx};
40 40
41 const auto mode = rp.PopEnum<PerformanceMode>(); 41 const auto mode = rp.PopEnum<PerformanceMode>();
@@ -46,7 +46,7 @@ private:
46 rb.PushEnum(controller.GetCurrentPerformanceConfiguration(mode)); 46 rb.PushEnum(controller.GetCurrentPerformanceConfiguration(mode));
47 } 47 }
48 48
49 void SetCpuOverclockEnabled(Kernel::HLERequestContext& ctx) { 49 void SetCpuOverclockEnabled(HLERequestContext& ctx) {
50 IPC::RequestParser rp{ctx}; 50 IPC::RequestParser rp{ctx};
51 51
52 const auto cpu_overclock_enabled = rp.Pop<bool>(); 52 const auto cpu_overclock_enabled = rp.Pop<bool>();
@@ -74,7 +74,7 @@ APM::APM(Core::System& system_, std::shared_ptr<Module> apm_, Controller& contro
74 74
75APM::~APM() = default; 75APM::~APM() = default;
76 76
77void APM::OpenSession(Kernel::HLERequestContext& ctx) { 77void APM::OpenSession(HLERequestContext& ctx) {
78 LOG_DEBUG(Service_APM, "called"); 78 LOG_DEBUG(Service_APM, "called");
79 79
80 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 80 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -82,14 +82,14 @@ void APM::OpenSession(Kernel::HLERequestContext& ctx) {
82 rb.PushIpcInterface<ISession>(system, controller); 82 rb.PushIpcInterface<ISession>(system, controller);
83} 83}
84 84
85void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) { 85void APM::GetPerformanceMode(HLERequestContext& ctx) {
86 LOG_DEBUG(Service_APM, "called"); 86 LOG_DEBUG(Service_APM, "called");
87 87
88 IPC::ResponseBuilder rb{ctx, 2}; 88 IPC::ResponseBuilder rb{ctx, 2};
89 rb.PushEnum(controller.GetCurrentPerformanceMode()); 89 rb.PushEnum(controller.GetCurrentPerformanceMode());
90} 90}
91 91
92void APM::IsCpuOverclockEnabled(Kernel::HLERequestContext& ctx) { 92void APM::IsCpuOverclockEnabled(HLERequestContext& ctx) {
93 LOG_WARNING(Service_APM, "(STUBBED) called"); 93 LOG_WARNING(Service_APM, "(STUBBED) called");
94 94
95 IPC::ResponseBuilder rb{ctx, 3}; 95 IPC::ResponseBuilder rb{ctx, 3};
@@ -117,7 +117,7 @@ APM_Sys::APM_Sys(Core::System& system_, Controller& controller_)
117 117
118APM_Sys::~APM_Sys() = default; 118APM_Sys::~APM_Sys() = default;
119 119
120void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) { 120void APM_Sys::GetPerformanceEvent(HLERequestContext& ctx) {
121 LOG_DEBUG(Service_APM, "called"); 121 LOG_DEBUG(Service_APM, "called");
122 122
123 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 123 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -125,7 +125,7 @@ void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) {
125 rb.PushIpcInterface<ISession>(system, controller); 125 rb.PushIpcInterface<ISession>(system, controller);
126} 126}
127 127
128void APM_Sys::SetCpuBoostMode(Kernel::HLERequestContext& ctx) { 128void APM_Sys::SetCpuBoostMode(HLERequestContext& ctx) {
129 IPC::RequestParser rp{ctx}; 129 IPC::RequestParser rp{ctx};
130 const auto mode = rp.PopEnum<CpuBoostMode>(); 130 const auto mode = rp.PopEnum<CpuBoostMode>();
131 131
@@ -137,7 +137,7 @@ void APM_Sys::SetCpuBoostMode(Kernel::HLERequestContext& ctx) {
137 rb.Push(ResultSuccess); 137 rb.Push(ResultSuccess);
138} 138}
139 139
140void APM_Sys::GetCurrentPerformanceConfiguration(Kernel::HLERequestContext& ctx) { 140void APM_Sys::GetCurrentPerformanceConfiguration(HLERequestContext& ctx) {
141 LOG_DEBUG(Service_APM, "called"); 141 LOG_DEBUG(Service_APM, "called");
142 142
143 IPC::ResponseBuilder rb{ctx, 3}; 143 IPC::ResponseBuilder rb{ctx, 3};
diff --git a/src/core/hle/service/apm/apm_interface.h b/src/core/hle/service/apm/apm_interface.h
index 0740fd4ba..58718453b 100644
--- a/src/core/hle/service/apm/apm_interface.h
+++ b/src/core/hle/service/apm/apm_interface.h
@@ -17,9 +17,9 @@ public:
17 ~APM() override; 17 ~APM() override;
18 18
19private: 19private:
20 void OpenSession(Kernel::HLERequestContext& ctx); 20 void OpenSession(HLERequestContext& ctx);
21 void GetPerformanceMode(Kernel::HLERequestContext& ctx); 21 void GetPerformanceMode(HLERequestContext& ctx);
22 void IsCpuOverclockEnabled(Kernel::HLERequestContext& ctx); 22 void IsCpuOverclockEnabled(HLERequestContext& ctx);
23 23
24 std::shared_ptr<Module> apm; 24 std::shared_ptr<Module> apm;
25 Controller& controller; 25 Controller& controller;
@@ -30,11 +30,11 @@ public:
30 explicit APM_Sys(Core::System& system_, Controller& controller); 30 explicit APM_Sys(Core::System& system_, Controller& controller);
31 ~APM_Sys() override; 31 ~APM_Sys() override;
32 32
33 void SetCpuBoostMode(Kernel::HLERequestContext& ctx); 33 void SetCpuBoostMode(HLERequestContext& ctx);
34 34
35private: 35private:
36 void GetPerformanceEvent(Kernel::HLERequestContext& ctx); 36 void GetPerformanceEvent(HLERequestContext& ctx);
37 void GetCurrentPerformanceConfiguration(Kernel::HLERequestContext& ctx); 37 void GetCurrentPerformanceConfiguration(HLERequestContext& ctx);
38 38
39 Controller& controller; 39 Controller& controller;
40}; 40};
diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp
index 5abf22ba4..7ad93be6b 100644
--- a/src/core/hle/service/audio/audctl.cpp
+++ b/src/core/hle/service/audio/audctl.cpp
@@ -2,8 +2,8 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/audio/audctl.h" 5#include "core/hle/service/audio/audctl.h"
6#include "core/hle/service/ipc_helpers.h"
7 7
8namespace Service::Audio { 8namespace Service::Audio {
9 9
@@ -72,7 +72,7 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
72 72
73AudCtl::~AudCtl() = default; 73AudCtl::~AudCtl() = default;
74 74
75void AudCtl::GetTargetVolumeMin(Kernel::HLERequestContext& ctx) { 75void AudCtl::GetTargetVolumeMin(HLERequestContext& ctx) {
76 LOG_DEBUG(Audio, "called."); 76 LOG_DEBUG(Audio, "called.");
77 77
78 // This service function is currently hardcoded on the 78 // This service function is currently hardcoded on the
@@ -84,7 +84,7 @@ void AudCtl::GetTargetVolumeMin(Kernel::HLERequestContext& ctx) {
84 rb.Push(target_min_volume); 84 rb.Push(target_min_volume);
85} 85}
86 86
87void AudCtl::GetTargetVolumeMax(Kernel::HLERequestContext& ctx) { 87void AudCtl::GetTargetVolumeMax(HLERequestContext& ctx) {
88 LOG_DEBUG(Audio, "called."); 88 LOG_DEBUG(Audio, "called.");
89 89
90 // This service function is currently hardcoded on the 90 // This service function is currently hardcoded on the
diff --git a/src/core/hle/service/audio/audctl.h b/src/core/hle/service/audio/audctl.h
index a27ff6cfe..8e31ac237 100644
--- a/src/core/hle/service/audio/audctl.h
+++ b/src/core/hle/service/audio/audctl.h
@@ -17,8 +17,8 @@ public:
17 ~AudCtl() override; 17 ~AudCtl() override;
18 18
19private: 19private:
20 void GetTargetVolumeMin(Kernel::HLERequestContext& ctx); 20 void GetTargetVolumeMin(HLERequestContext& ctx);
21 void GetTargetVolumeMax(Kernel::HLERequestContext& ctx); 21 void GetTargetVolumeMax(HLERequestContext& ctx);
22}; 22};
23 23
24} // namespace Service::Audio 24} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp
index 053e8f9dd..f0640c64f 100644
--- a/src/core/hle/service/audio/audin_u.cpp
+++ b/src/core/hle/service/audio/audin_u.cpp
@@ -7,9 +7,9 @@
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "common/string_util.h" 8#include "common/string_util.h"
9#include "core/core.h" 9#include "core/core.h"
10#include "core/hle/ipc_helpers.h"
11#include "core/hle/kernel/k_event.h" 10#include "core/hle/kernel/k_event.h"
12#include "core/hle/service/audio/audin_u.h" 11#include "core/hle/service/audio/audin_u.h"
12#include "core/hle/service/ipc_helpers.h"
13 13
14namespace Service::Audio { 14namespace Service::Audio {
15using namespace AudioCore::AudioIn; 15using namespace AudioCore::AudioIn;
@@ -61,7 +61,7 @@ public:
61 } 61 }
62 62
63private: 63private:
64 void GetAudioInState(Kernel::HLERequestContext& ctx) { 64 void GetAudioInState(HLERequestContext& ctx) {
65 const auto state = static_cast<u32>(impl->GetState()); 65 const auto state = static_cast<u32>(impl->GetState());
66 66
67 LOG_DEBUG(Service_Audio, "called. State={}", state); 67 LOG_DEBUG(Service_Audio, "called. State={}", state);
@@ -71,7 +71,7 @@ private:
71 rb.Push(state); 71 rb.Push(state);
72 } 72 }
73 73
74 void Start(Kernel::HLERequestContext& ctx) { 74 void Start(HLERequestContext& ctx) {
75 LOG_DEBUG(Service_Audio, "called"); 75 LOG_DEBUG(Service_Audio, "called");
76 76
77 auto result = impl->StartSystem(); 77 auto result = impl->StartSystem();
@@ -80,7 +80,7 @@ private:
80 rb.Push(result); 80 rb.Push(result);
81 } 81 }
82 82
83 void Stop(Kernel::HLERequestContext& ctx) { 83 void Stop(HLERequestContext& ctx) {
84 LOG_DEBUG(Service_Audio, "called"); 84 LOG_DEBUG(Service_Audio, "called");
85 85
86 auto result = impl->StopSystem(); 86 auto result = impl->StopSystem();
@@ -89,7 +89,7 @@ private:
89 rb.Push(result); 89 rb.Push(result);
90 } 90 }
91 91
92 void AppendAudioInBuffer(Kernel::HLERequestContext& ctx) { 92 void AppendAudioInBuffer(HLERequestContext& ctx) {
93 IPC::RequestParser rp{ctx}; 93 IPC::RequestParser rp{ctx};
94 u64 tag = rp.PopRaw<u64>(); 94 u64 tag = rp.PopRaw<u64>();
95 95
@@ -111,7 +111,7 @@ private:
111 rb.Push(result); 111 rb.Push(result);
112 } 112 }
113 113
114 void RegisterBufferEvent(Kernel::HLERequestContext& ctx) { 114 void RegisterBufferEvent(HLERequestContext& ctx) {
115 LOG_DEBUG(Service_Audio, "called"); 115 LOG_DEBUG(Service_Audio, "called");
116 116
117 auto& buffer_event = impl->GetBufferEvent(); 117 auto& buffer_event = impl->GetBufferEvent();
@@ -121,7 +121,7 @@ private:
121 rb.PushCopyObjects(buffer_event); 121 rb.PushCopyObjects(buffer_event);
122 } 122 }
123 123
124 void GetReleasedAudioInBuffer(Kernel::HLERequestContext& ctx) { 124 void GetReleasedAudioInBuffer(HLERequestContext& ctx) {
125 const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); 125 const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>();
126 std::vector<u64> released_buffers(write_buffer_size); 126 std::vector<u64> released_buffers(write_buffer_size);
127 127
@@ -141,7 +141,7 @@ private:
141 rb.Push(count); 141 rb.Push(count);
142 } 142 }
143 143
144 void ContainsAudioInBuffer(Kernel::HLERequestContext& ctx) { 144 void ContainsAudioInBuffer(HLERequestContext& ctx) {
145 IPC::RequestParser rp{ctx}; 145 IPC::RequestParser rp{ctx};
146 146
147 const u64 tag{rp.Pop<u64>()}; 147 const u64 tag{rp.Pop<u64>()};
@@ -154,7 +154,7 @@ private:
154 rb.Push(buffer_queued); 154 rb.Push(buffer_queued);
155 } 155 }
156 156
157 void GetAudioInBufferCount(Kernel::HLERequestContext& ctx) { 157 void GetAudioInBufferCount(HLERequestContext& ctx) {
158 const auto buffer_count = impl->GetBufferCount(); 158 const auto buffer_count = impl->GetBufferCount();
159 159
160 LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count); 160 LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count);
@@ -165,7 +165,7 @@ private:
165 rb.Push(buffer_count); 165 rb.Push(buffer_count);
166 } 166 }
167 167
168 void SetDeviceGain(Kernel::HLERequestContext& ctx) { 168 void SetDeviceGain(HLERequestContext& ctx) {
169 IPC::RequestParser rp{ctx}; 169 IPC::RequestParser rp{ctx};
170 170
171 const auto volume{rp.Pop<f32>()}; 171 const auto volume{rp.Pop<f32>()};
@@ -177,7 +177,7 @@ private:
177 rb.Push(ResultSuccess); 177 rb.Push(ResultSuccess);
178 } 178 }
179 179
180 void GetDeviceGain(Kernel::HLERequestContext& ctx) { 180 void GetDeviceGain(HLERequestContext& ctx) {
181 auto volume{impl->GetVolume()}; 181 auto volume{impl->GetVolume()};
182 182
183 LOG_DEBUG(Service_Audio, "called. Gain {}", volume); 183 LOG_DEBUG(Service_Audio, "called. Gain {}", volume);
@@ -187,7 +187,7 @@ private:
187 rb.Push(volume); 187 rb.Push(volume);
188 } 188 }
189 189
190 void FlushAudioInBuffers(Kernel::HLERequestContext& ctx) { 190 void FlushAudioInBuffers(HLERequestContext& ctx) {
191 bool flushed{impl->FlushAudioInBuffers()}; 191 bool flushed{impl->FlushAudioInBuffers()};
192 192
193 LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", flushed); 193 LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", flushed);
@@ -203,9 +203,8 @@ private:
203}; 203};
204 204
205AudInU::AudInU(Core::System& system_) 205AudInU::AudInU(Core::System& system_)
206 : ServiceFramework{system_, "audin:u", ServiceThreadType::CreateNew}, 206 : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"},
207 service_context{system_, "AudInU"}, impl{std::make_unique<AudioCore::AudioIn::Manager>( 207 impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)} {
208 system_)} {
209 // clang-format off 208 // clang-format off
210 static const FunctionInfo functions[] = { 209 static const FunctionInfo functions[] = {
211 {0, &AudInU::ListAudioIns, "ListAudioIns"}, 210 {0, &AudInU::ListAudioIns, "ListAudioIns"},
@@ -222,7 +221,7 @@ AudInU::AudInU(Core::System& system_)
222 221
223AudInU::~AudInU() = default; 222AudInU::~AudInU() = default;
224 223
225void AudInU::ListAudioIns(Kernel::HLERequestContext& ctx) { 224void AudInU::ListAudioIns(HLERequestContext& ctx) {
226 using namespace AudioCore::AudioRenderer; 225 using namespace AudioCore::AudioRenderer;
227 226
228 LOG_DEBUG(Service_Audio, "called"); 227 LOG_DEBUG(Service_Audio, "called");
@@ -242,7 +241,7 @@ void AudInU::ListAudioIns(Kernel::HLERequestContext& ctx) {
242 rb.Push(out_count); 241 rb.Push(out_count);
243} 242}
244 243
245void AudInU::ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx) { 244void AudInU::ListAudioInsAutoFiltered(HLERequestContext& ctx) {
246 using namespace AudioCore::AudioRenderer; 245 using namespace AudioCore::AudioRenderer;
247 246
248 LOG_DEBUG(Service_Audio, "called"); 247 LOG_DEBUG(Service_Audio, "called");
@@ -262,7 +261,7 @@ void AudInU::ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx) {
262 rb.Push(out_count); 261 rb.Push(out_count);
263} 262}
264 263
265void AudInU::OpenAudioIn(Kernel::HLERequestContext& ctx) { 264void AudInU::OpenAudioIn(HLERequestContext& ctx) {
266 IPC::RequestParser rp{ctx}; 265 IPC::RequestParser rp{ctx};
267 auto in_params{rp.PopRaw<AudioInParameter>()}; 266 auto in_params{rp.PopRaw<AudioInParameter>()};
268 auto applet_resource_user_id{rp.PopRaw<u64>()}; 267 auto applet_resource_user_id{rp.PopRaw<u64>()};
@@ -312,7 +311,7 @@ void AudInU::OpenAudioIn(Kernel::HLERequestContext& ctx) {
312 rb.PushIpcInterface<IAudioIn>(audio_in); 311 rb.PushIpcInterface<IAudioIn>(audio_in);
313} 312}
314 313
315void AudInU::OpenAudioInProtocolSpecified(Kernel::HLERequestContext& ctx) { 314void AudInU::OpenAudioInProtocolSpecified(HLERequestContext& ctx) {
316 IPC::RequestParser rp{ctx}; 315 IPC::RequestParser rp{ctx};
317 auto protocol_specified{rp.PopRaw<u64>()}; 316 auto protocol_specified{rp.PopRaw<u64>()};
318 auto in_params{rp.PopRaw<AudioInParameter>()}; 317 auto in_params{rp.PopRaw<AudioInParameter>()};
diff --git a/src/core/hle/service/audio/audin_u.h b/src/core/hle/service/audio/audin_u.h
index b45fda78a..51e770ff9 100644
--- a/src/core/hle/service/audio/audin_u.h
+++ b/src/core/hle/service/audio/audin_u.h
@@ -12,10 +12,6 @@ namespace Core {
12class System; 12class System;
13} 13}
14 14
15namespace Kernel {
16class HLERequestContext;
17}
18
19namespace AudioCore::AudioOut { 15namespace AudioCore::AudioOut {
20class Manager; 16class Manager;
21class In; 17class In;
@@ -29,11 +25,11 @@ public:
29 ~AudInU() override; 25 ~AudInU() override;
30 26
31private: 27private:
32 void ListAudioIns(Kernel::HLERequestContext& ctx); 28 void ListAudioIns(HLERequestContext& ctx);
33 void ListAudioInsAutoFiltered(Kernel::HLERequestContext& ctx); 29 void ListAudioInsAutoFiltered(HLERequestContext& ctx);
34 void OpenInOutImpl(Kernel::HLERequestContext& ctx); 30 void OpenInOutImpl(HLERequestContext& ctx);
35 void OpenAudioIn(Kernel::HLERequestContext& ctx); 31 void OpenAudioIn(HLERequestContext& ctx);
36 void OpenAudioInProtocolSpecified(Kernel::HLERequestContext& ctx); 32 void OpenAudioInProtocolSpecified(HLERequestContext& ctx);
37 33
38 KernelHelpers::ServiceContext service_context; 34 KernelHelpers::ServiceContext service_context;
39 std::unique_ptr<AudioCore::AudioIn::Manager> impl; 35 std::unique_ptr<AudioCore::AudioIn::Manager> impl;
diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp
index ed36e3448..dccd16309 100644
--- a/src/core/hle/service/audio/audio.cpp
+++ b/src/core/hle/service/audio/audio.cpp
@@ -1,6 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h"
4#include "core/hle/service/audio/audctl.h" 5#include "core/hle/service/audio/audctl.h"
5#include "core/hle/service/audio/audin_u.h" 6#include "core/hle/service/audio/audin_u.h"
6#include "core/hle/service/audio/audio.h" 7#include "core/hle/service/audio/audio.h"
@@ -9,18 +10,22 @@
9#include "core/hle/service/audio/audrec_u.h" 10#include "core/hle/service/audio/audrec_u.h"
10#include "core/hle/service/audio/audren_u.h" 11#include "core/hle/service/audio/audren_u.h"
11#include "core/hle/service/audio/hwopus.h" 12#include "core/hle/service/audio/hwopus.h"
13#include "core/hle/service/server_manager.h"
12#include "core/hle/service/service.h" 14#include "core/hle/service/service.h"
13 15
14namespace Service::Audio { 16namespace Service::Audio {
15 17
16void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 18void LoopProcess(Core::System& system) {
17 std::make_shared<AudCtl>(system)->InstallAsService(service_manager); 19 auto server_manager = std::make_unique<ServerManager>(system);
18 std::make_shared<AudOutU>(system)->InstallAsService(service_manager); 20
19 std::make_shared<AudInU>(system)->InstallAsService(service_manager); 21 server_manager->RegisterNamedService("audctl", std::make_shared<AudCtl>(system));
20 std::make_shared<AudRecA>(system)->InstallAsService(service_manager); 22 server_manager->RegisterNamedService("audout:u", std::make_shared<AudOutU>(system));
21 std::make_shared<AudRecU>(system)->InstallAsService(service_manager); 23 server_manager->RegisterNamedService("audin:u", std::make_shared<AudInU>(system));
22 std::make_shared<AudRenU>(system)->InstallAsService(service_manager); 24 server_manager->RegisterNamedService("audrec:a", std::make_shared<AudRecA>(system));
23 std::make_shared<HwOpus>(system)->InstallAsService(service_manager); 25 server_manager->RegisterNamedService("audrec:u", std::make_shared<AudRecU>(system));
26 server_manager->RegisterNamedService("audren:u", std::make_shared<AudRenU>(system));
27 server_manager->RegisterNamedService("hwopus", std::make_shared<HwOpus>(system));
28 ServerManager::RunServer(std::move(server_manager));
24} 29}
25 30
26} // namespace Service::Audio 31} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audio.h b/src/core/hle/service/audio/audio.h
index bbb2214e4..d70f022c7 100644
--- a/src/core/hle/service/audio/audio.h
+++ b/src/core/hle/service/audio/audio.h
@@ -13,7 +13,6 @@ class ServiceManager;
13 13
14namespace Service::Audio { 14namespace Service::Audio {
15 15
16/// Registers all Audio services with the specified service manager. 16void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 17
19} // namespace Service::Audio 18} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 29751f075..23b8be993 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -12,10 +12,10 @@
12#include "common/string_util.h" 12#include "common/string_util.h"
13#include "common/swap.h" 13#include "common/swap.h"
14#include "core/core.h" 14#include "core/core.h"
15#include "core/hle/ipc_helpers.h"
16#include "core/hle/kernel/k_event.h" 15#include "core/hle/kernel/k_event.h"
17#include "core/hle/service/audio/audout_u.h" 16#include "core/hle/service/audio/audout_u.h"
18#include "core/hle/service/audio/errors.h" 17#include "core/hle/service/audio/errors.h"
18#include "core/hle/service/ipc_helpers.h"
19#include "core/memory.h" 19#include "core/memory.h"
20 20
21namespace Service::Audio { 21namespace Service::Audio {
@@ -26,9 +26,8 @@ public:
26 explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager, 26 explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager,
27 size_t session_id, const std::string& device_name, 27 size_t session_id, const std::string& device_name,
28 const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id) 28 const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id)
29 : ServiceFramework{system_, "IAudioOut", ServiceThreadType::CreateNew}, 29 : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"},
30 service_context{system_, "IAudioOut"}, event{service_context.CreateEvent( 30 event{service_context.CreateEvent("AudioOutEvent")},
31 "AudioOutEvent")},
32 impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} { 31 impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} {
33 32
34 // clang-format off 33 // clang-format off
@@ -68,7 +67,7 @@ public:
68 } 67 }
69 68
70private: 69private:
71 void GetAudioOutState(Kernel::HLERequestContext& ctx) { 70 void GetAudioOutState(HLERequestContext& ctx) {
72 const auto state = static_cast<u32>(impl->GetState()); 71 const auto state = static_cast<u32>(impl->GetState());
73 72
74 LOG_DEBUG(Service_Audio, "called. State={}", state); 73 LOG_DEBUG(Service_Audio, "called. State={}", state);
@@ -78,7 +77,7 @@ private:
78 rb.Push(state); 77 rb.Push(state);
79 } 78 }
80 79
81 void Start(Kernel::HLERequestContext& ctx) { 80 void Start(HLERequestContext& ctx) {
82 LOG_DEBUG(Service_Audio, "called"); 81 LOG_DEBUG(Service_Audio, "called");
83 82
84 auto result = impl->StartSystem(); 83 auto result = impl->StartSystem();
@@ -87,7 +86,7 @@ private:
87 rb.Push(result); 86 rb.Push(result);
88 } 87 }
89 88
90 void Stop(Kernel::HLERequestContext& ctx) { 89 void Stop(HLERequestContext& ctx) {
91 LOG_DEBUG(Service_Audio, "called"); 90 LOG_DEBUG(Service_Audio, "called");
92 91
93 auto result = impl->StopSystem(); 92 auto result = impl->StopSystem();
@@ -96,7 +95,7 @@ private:
96 rb.Push(result); 95 rb.Push(result);
97 } 96 }
98 97
99 void AppendAudioOutBuffer(Kernel::HLERequestContext& ctx) { 98 void AppendAudioOutBuffer(HLERequestContext& ctx) {
100 IPC::RequestParser rp{ctx}; 99 IPC::RequestParser rp{ctx};
101 u64 tag = rp.PopRaw<u64>(); 100 u64 tag = rp.PopRaw<u64>();
102 101
@@ -118,7 +117,7 @@ private:
118 rb.Push(result); 117 rb.Push(result);
119 } 118 }
120 119
121 void RegisterBufferEvent(Kernel::HLERequestContext& ctx) { 120 void RegisterBufferEvent(HLERequestContext& ctx) {
122 LOG_DEBUG(Service_Audio, "called"); 121 LOG_DEBUG(Service_Audio, "called");
123 122
124 auto& buffer_event = impl->GetBufferEvent(); 123 auto& buffer_event = impl->GetBufferEvent();
@@ -128,7 +127,7 @@ private:
128 rb.PushCopyObjects(buffer_event); 127 rb.PushCopyObjects(buffer_event);
129 } 128 }
130 129
131 void GetReleasedAudioOutBuffers(Kernel::HLERequestContext& ctx) { 130 void GetReleasedAudioOutBuffers(HLERequestContext& ctx) {
132 const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); 131 const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>();
133 std::vector<u64> released_buffers(write_buffer_size); 132 std::vector<u64> released_buffers(write_buffer_size);
134 133
@@ -148,7 +147,7 @@ private:
148 rb.Push(count); 147 rb.Push(count);
149 } 148 }
150 149
151 void ContainsAudioOutBuffer(Kernel::HLERequestContext& ctx) { 150 void ContainsAudioOutBuffer(HLERequestContext& ctx) {
152 IPC::RequestParser rp{ctx}; 151 IPC::RequestParser rp{ctx};
153 152
154 const u64 tag{rp.Pop<u64>()}; 153 const u64 tag{rp.Pop<u64>()};
@@ -161,7 +160,7 @@ private:
161 rb.Push(buffer_queued); 160 rb.Push(buffer_queued);
162 } 161 }
163 162
164 void GetAudioOutBufferCount(Kernel::HLERequestContext& ctx) { 163 void GetAudioOutBufferCount(HLERequestContext& ctx) {
165 const auto buffer_count = impl->GetBufferCount(); 164 const auto buffer_count = impl->GetBufferCount();
166 165
167 LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count); 166 LOG_DEBUG(Service_Audio, "called. Buffer count={}", buffer_count);
@@ -172,7 +171,7 @@ private:
172 rb.Push(buffer_count); 171 rb.Push(buffer_count);
173 } 172 }
174 173
175 void GetAudioOutPlayedSampleCount(Kernel::HLERequestContext& ctx) { 174 void GetAudioOutPlayedSampleCount(HLERequestContext& ctx) {
176 const auto samples_played = impl->GetPlayedSampleCount(); 175 const auto samples_played = impl->GetPlayedSampleCount();
177 176
178 LOG_DEBUG(Service_Audio, "called. Played samples={}", samples_played); 177 LOG_DEBUG(Service_Audio, "called. Played samples={}", samples_played);
@@ -183,7 +182,7 @@ private:
183 rb.Push(samples_played); 182 rb.Push(samples_played);
184 } 183 }
185 184
186 void FlushAudioOutBuffers(Kernel::HLERequestContext& ctx) { 185 void FlushAudioOutBuffers(HLERequestContext& ctx) {
187 bool flushed{impl->FlushAudioOutBuffers()}; 186 bool flushed{impl->FlushAudioOutBuffers()};
188 187
189 LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", flushed); 188 LOG_DEBUG(Service_Audio, "called. Were any buffers flushed? {}", flushed);
@@ -193,7 +192,7 @@ private:
193 rb.Push(flushed); 192 rb.Push(flushed);
194 } 193 }
195 194
196 void SetAudioOutVolume(Kernel::HLERequestContext& ctx) { 195 void SetAudioOutVolume(HLERequestContext& ctx) {
197 IPC::RequestParser rp{ctx}; 196 IPC::RequestParser rp{ctx};
198 const auto volume = rp.Pop<f32>(); 197 const auto volume = rp.Pop<f32>();
199 198
@@ -205,7 +204,7 @@ private:
205 rb.Push(ResultSuccess); 204 rb.Push(ResultSuccess);
206 } 205 }
207 206
208 void GetAudioOutVolume(Kernel::HLERequestContext& ctx) { 207 void GetAudioOutVolume(HLERequestContext& ctx) {
209 const auto volume = impl->GetVolume(); 208 const auto volume = impl->GetVolume();
210 209
211 LOG_DEBUG(Service_Audio, "called. Volume={}", volume); 210 LOG_DEBUG(Service_Audio, "called. Volume={}", volume);
@@ -221,9 +220,8 @@ private:
221}; 220};
222 221
223AudOutU::AudOutU(Core::System& system_) 222AudOutU::AudOutU(Core::System& system_)
224 : ServiceFramework{system_, "audout:u", ServiceThreadType::CreateNew}, 223 : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"},
225 service_context{system_, "AudOutU"}, impl{std::make_unique<AudioCore::AudioOut::Manager>( 224 impl{std::make_unique<AudioCore::AudioOut::Manager>(system_)} {
226 system_)} {
227 // clang-format off 225 // clang-format off
228 static const FunctionInfo functions[] = { 226 static const FunctionInfo functions[] = {
229 {0, &AudOutU::ListAudioOuts, "ListAudioOuts"}, 227 {0, &AudOutU::ListAudioOuts, "ListAudioOuts"},
@@ -238,7 +236,7 @@ AudOutU::AudOutU(Core::System& system_)
238 236
239AudOutU::~AudOutU() = default; 237AudOutU::~AudOutU() = default;
240 238
241void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) { 239void AudOutU::ListAudioOuts(HLERequestContext& ctx) {
242 using namespace AudioCore::AudioRenderer; 240 using namespace AudioCore::AudioRenderer;
243 241
244 std::scoped_lock l{impl->mutex}; 242 std::scoped_lock l{impl->mutex};
@@ -260,7 +258,7 @@ void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) {
260 rb.Push<u32>(static_cast<u32>(device_names.size())); 258 rb.Push<u32>(static_cast<u32>(device_names.size()));
261} 259}
262 260
263void AudOutU::OpenAudioOut(Kernel::HLERequestContext& ctx) { 261void AudOutU::OpenAudioOut(HLERequestContext& ctx) {
264 IPC::RequestParser rp{ctx}; 262 IPC::RequestParser rp{ctx};
265 auto in_params{rp.PopRaw<AudioOutParameter>()}; 263 auto in_params{rp.PopRaw<AudioOutParameter>()};
266 auto applet_resource_user_id{rp.PopRaw<u64>()}; 264 auto applet_resource_user_id{rp.PopRaw<u64>()};
diff --git a/src/core/hle/service/audio/audout_u.h b/src/core/hle/service/audio/audout_u.h
index fdc0ee754..8f288c6e0 100644
--- a/src/core/hle/service/audio/audout_u.h
+++ b/src/core/hle/service/audio/audout_u.h
@@ -12,10 +12,6 @@ namespace Core {
12class System; 12class System;
13} 13}
14 14
15namespace Kernel {
16class HLERequestContext;
17}
18
19namespace AudioCore::AudioOut { 15namespace AudioCore::AudioOut {
20class Manager; 16class Manager;
21class Out; 17class Out;
@@ -31,8 +27,8 @@ public:
31 ~AudOutU() override; 27 ~AudOutU() override;
32 28
33private: 29private:
34 void ListAudioOuts(Kernel::HLERequestContext& ctx); 30 void ListAudioOuts(HLERequestContext& ctx);
35 void OpenAudioOut(Kernel::HLERequestContext& ctx); 31 void OpenAudioOut(HLERequestContext& ctx);
36 32
37 KernelHelpers::ServiceContext service_context; 33 KernelHelpers::ServiceContext service_context;
38 std::unique_ptr<AudioCore::AudioOut::Manager> impl; 34 std::unique_ptr<AudioCore::AudioOut::Manager> impl;
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 7d730421d..7086d4750 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -17,12 +17,12 @@
17#include "common/polyfill_ranges.h" 17#include "common/polyfill_ranges.h"
18#include "common/string_util.h" 18#include "common/string_util.h"
19#include "core/core.h" 19#include "core/core.h"
20#include "core/hle/ipc_helpers.h"
21#include "core/hle/kernel/k_event.h" 20#include "core/hle/kernel/k_event.h"
22#include "core/hle/kernel/k_process.h" 21#include "core/hle/kernel/k_process.h"
23#include "core/hle/kernel/k_transfer_memory.h" 22#include "core/hle/kernel/k_transfer_memory.h"
24#include "core/hle/service/audio/audren_u.h" 23#include "core/hle/service/audio/audren_u.h"
25#include "core/hle/service/audio/errors.h" 24#include "core/hle/service/audio/errors.h"
25#include "core/hle/service/ipc_helpers.h"
26#include "core/memory.h" 26#include "core/memory.h"
27 27
28using namespace AudioCore::AudioRenderer; 28using namespace AudioCore::AudioRenderer;
@@ -35,10 +35,9 @@ public:
35 AudioCore::AudioRendererParameterInternal& params, 35 AudioCore::AudioRendererParameterInternal& params,
36 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, 36 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
37 u32 process_handle, u64 applet_resource_user_id, s32 session_id) 37 u32 process_handle, u64 applet_resource_user_id, s32 session_id)
38 : ServiceFramework{system_, "IAudioRenderer", ServiceThreadType::CreateNew}, 38 : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"},
39 service_context{system_, "IAudioRenderer"}, rendered_event{service_context.CreateEvent( 39 rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_},
40 "IAudioRendererEvent")}, 40 impl{std::make_unique<Renderer>(system_, manager, rendered_event)} {
41 manager{manager_}, impl{std::make_unique<Renderer>(system_, manager, rendered_event)} {
42 // clang-format off 41 // clang-format off
43 static const FunctionInfo functions[] = { 42 static const FunctionInfo functions[] = {
44 {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, 43 {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"},
@@ -69,7 +68,7 @@ public:
69 } 68 }
70 69
71private: 70private:
72 void GetSampleRate(Kernel::HLERequestContext& ctx) { 71 void GetSampleRate(HLERequestContext& ctx) {
73 const auto sample_rate{impl->GetSystem().GetSampleRate()}; 72 const auto sample_rate{impl->GetSystem().GetSampleRate()};
74 73
75 LOG_DEBUG(Service_Audio, "called. Sample rate {}", sample_rate); 74 LOG_DEBUG(Service_Audio, "called. Sample rate {}", sample_rate);
@@ -79,7 +78,7 @@ private:
79 rb.Push(sample_rate); 78 rb.Push(sample_rate);
80 } 79 }
81 80
82 void GetSampleCount(Kernel::HLERequestContext& ctx) { 81 void GetSampleCount(HLERequestContext& ctx) {
83 const auto sample_count{impl->GetSystem().GetSampleCount()}; 82 const auto sample_count{impl->GetSystem().GetSampleCount()};
84 83
85 LOG_DEBUG(Service_Audio, "called. Sample count {}", sample_count); 84 LOG_DEBUG(Service_Audio, "called. Sample count {}", sample_count);
@@ -89,7 +88,7 @@ private:
89 rb.Push(sample_count); 88 rb.Push(sample_count);
90 } 89 }
91 90
92 void GetState(Kernel::HLERequestContext& ctx) { 91 void GetState(HLERequestContext& ctx) {
93 const u32 state{!impl->GetSystem().IsActive()}; 92 const u32 state{!impl->GetSystem().IsActive()};
94 93
95 LOG_DEBUG(Service_Audio, "called, state {}", state); 94 LOG_DEBUG(Service_Audio, "called, state {}", state);
@@ -99,7 +98,7 @@ private:
99 rb.Push(state); 98 rb.Push(state);
100 } 99 }
101 100
102 void GetMixBufferCount(Kernel::HLERequestContext& ctx) { 101 void GetMixBufferCount(HLERequestContext& ctx) {
103 LOG_DEBUG(Service_Audio, "called"); 102 LOG_DEBUG(Service_Audio, "called");
104 103
105 const auto buffer_count{impl->GetSystem().GetMixBufferCount()}; 104 const auto buffer_count{impl->GetSystem().GetMixBufferCount()};
@@ -109,7 +108,7 @@ private:
109 rb.Push(buffer_count); 108 rb.Push(buffer_count);
110 } 109 }
111 110
112 void RequestUpdate(Kernel::HLERequestContext& ctx) { 111 void RequestUpdate(HLERequestContext& ctx) {
113 LOG_TRACE(Service_Audio, "called"); 112 LOG_TRACE(Service_Audio, "called");
114 113
115 const auto input{ctx.ReadBuffer(0)}; 114 const auto input{ctx.ReadBuffer(0)};
@@ -148,7 +147,7 @@ private:
148 rb.Push(result); 147 rb.Push(result);
149 } 148 }
150 149
151 void Start(Kernel::HLERequestContext& ctx) { 150 void Start(HLERequestContext& ctx) {
152 LOG_DEBUG(Service_Audio, "called"); 151 LOG_DEBUG(Service_Audio, "called");
153 152
154 impl->Start(); 153 impl->Start();
@@ -157,7 +156,7 @@ private:
157 rb.Push(ResultSuccess); 156 rb.Push(ResultSuccess);
158 } 157 }
159 158
160 void Stop(Kernel::HLERequestContext& ctx) { 159 void Stop(HLERequestContext& ctx) {
161 LOG_DEBUG(Service_Audio, "called"); 160 LOG_DEBUG(Service_Audio, "called");
162 161
163 impl->Stop(); 162 impl->Stop();
@@ -166,12 +165,12 @@ private:
166 rb.Push(ResultSuccess); 165 rb.Push(ResultSuccess);
167 } 166 }
168 167
169 void QuerySystemEvent(Kernel::HLERequestContext& ctx) { 168 void QuerySystemEvent(HLERequestContext& ctx) {
170 LOG_DEBUG(Service_Audio, "called"); 169 LOG_DEBUG(Service_Audio, "called");
171 170
172 if (impl->GetSystem().GetExecutionMode() == AudioCore::ExecutionMode::Manual) { 171 if (impl->GetSystem().GetExecutionMode() == AudioCore::ExecutionMode::Manual) {
173 IPC::ResponseBuilder rb{ctx, 2}; 172 IPC::ResponseBuilder rb{ctx, 2};
174 rb.Push(ERR_NOT_SUPPORTED); 173 rb.Push(Audio::ResultNotSupported);
175 return; 174 return;
176 } 175 }
177 176
@@ -180,7 +179,7 @@ private:
180 rb.PushCopyObjects(rendered_event->GetReadableEvent()); 179 rb.PushCopyObjects(rendered_event->GetReadableEvent());
181 } 180 }
182 181
183 void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) { 182 void SetRenderingTimeLimit(HLERequestContext& ctx) {
184 LOG_DEBUG(Service_Audio, "called"); 183 LOG_DEBUG(Service_Audio, "called");
185 184
186 IPC::RequestParser rp{ctx}; 185 IPC::RequestParser rp{ctx};
@@ -193,7 +192,7 @@ private:
193 rb.Push(ResultSuccess); 192 rb.Push(ResultSuccess);
194 } 193 }
195 194
196 void GetRenderingTimeLimit(Kernel::HLERequestContext& ctx) { 195 void GetRenderingTimeLimit(HLERequestContext& ctx) {
197 LOG_DEBUG(Service_Audio, "called"); 196 LOG_DEBUG(Service_Audio, "called");
198 197
199 auto& system_ = impl->GetSystem(); 198 auto& system_ = impl->GetSystem();
@@ -204,11 +203,11 @@ private:
204 rb.Push(time); 203 rb.Push(time);
205 } 204 }
206 205
207 void ExecuteAudioRendererRendering(Kernel::HLERequestContext& ctx) { 206 void ExecuteAudioRendererRendering(HLERequestContext& ctx) {
208 LOG_DEBUG(Service_Audio, "called"); 207 LOG_DEBUG(Service_Audio, "called");
209 } 208 }
210 209
211 void SetVoiceDropParameter(Kernel::HLERequestContext& ctx) { 210 void SetVoiceDropParameter(HLERequestContext& ctx) {
212 LOG_DEBUG(Service_Audio, "called"); 211 LOG_DEBUG(Service_Audio, "called");
213 212
214 IPC::RequestParser rp{ctx}; 213 IPC::RequestParser rp{ctx};
@@ -221,7 +220,7 @@ private:
221 rb.Push(ResultSuccess); 220 rb.Push(ResultSuccess);
222 } 221 }
223 222
224 void GetVoiceDropParameter(Kernel::HLERequestContext& ctx) { 223 void GetVoiceDropParameter(HLERequestContext& ctx) {
225 LOG_DEBUG(Service_Audio, "called"); 224 LOG_DEBUG(Service_Audio, "called");
226 225
227 auto& system_ = impl->GetSystem(); 226 auto& system_ = impl->GetSystem();
@@ -243,10 +242,8 @@ class IAudioDevice final : public ServiceFramework<IAudioDevice> {
243public: 242public:
244 explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision, 243 explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision,
245 u32 device_num) 244 u32 device_num)
246 : ServiceFramework{system_, "IAudioDevice", ServiceThreadType::CreateNew}, 245 : ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"},
247 service_context{system_, "IAudioDevice"}, impl{std::make_unique<AudioDevice>( 246 impl{std::make_unique<AudioDevice>(system_, applet_resource_user_id, revision)},
248 system_, applet_resource_user_id,
249 revision)},
250 event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} { 247 event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} {
251 static const FunctionInfo functions[] = { 248 static const FunctionInfo functions[] = {
252 {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, 249 {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"},
@@ -274,7 +271,7 @@ public:
274 } 271 }
275 272
276private: 273private:
277 void ListAudioDeviceName(Kernel::HLERequestContext& ctx) { 274 void ListAudioDeviceName(HLERequestContext& ctx) {
278 const size_t in_count = ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>(); 275 const size_t in_count = ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>();
279 276
280 std::vector<AudioDevice::AudioDeviceName> out_names{}; 277 std::vector<AudioDevice::AudioDeviceName> out_names{};
@@ -302,7 +299,7 @@ private:
302 rb.Push(out_count); 299 rb.Push(out_count);
303 } 300 }
304 301
305 void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) { 302 void SetAudioDeviceOutputVolume(HLERequestContext& ctx) {
306 IPC::RequestParser rp{ctx}; 303 IPC::RequestParser rp{ctx};
307 const f32 volume = rp.Pop<f32>(); 304 const f32 volume = rp.Pop<f32>();
308 305
@@ -319,7 +316,7 @@ private:
319 rb.Push(ResultSuccess); 316 rb.Push(ResultSuccess);
320 } 317 }
321 318
322 void GetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) { 319 void GetAudioDeviceOutputVolume(HLERequestContext& ctx) {
323 const auto device_name_buffer = ctx.ReadBuffer(); 320 const auto device_name_buffer = ctx.ReadBuffer();
324 const std::string name = Common::StringFromBuffer(device_name_buffer); 321 const std::string name = Common::StringFromBuffer(device_name_buffer);
325 322
@@ -335,7 +332,7 @@ private:
335 rb.Push(volume); 332 rb.Push(volume);
336 } 333 }
337 334
338 void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) { 335 void GetActiveAudioDeviceName(HLERequestContext& ctx) {
339 const auto write_size = ctx.GetWriteBufferSize(); 336 const auto write_size = ctx.GetWriteBufferSize();
340 std::string out_name{"AudioTvOutput"}; 337 std::string out_name{"AudioTvOutput"};
341 338
@@ -349,7 +346,7 @@ private:
349 rb.Push(ResultSuccess); 346 rb.Push(ResultSuccess);
350 } 347 }
351 348
352 void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { 349 void QueryAudioDeviceSystemEvent(HLERequestContext& ctx) {
353 LOG_DEBUG(Service_Audio, "(STUBBED) called"); 350 LOG_DEBUG(Service_Audio, "(STUBBED) called");
354 351
355 event->Signal(); 352 event->Signal();
@@ -359,7 +356,7 @@ private:
359 rb.PushCopyObjects(event->GetReadableEvent()); 356 rb.PushCopyObjects(event->GetReadableEvent());
360 } 357 }
361 358
362 void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { 359 void GetActiveChannelCount(HLERequestContext& ctx) {
363 const auto& sink{system.AudioCore().GetOutputSink()}; 360 const auto& sink{system.AudioCore().GetOutputSink()};
364 u32 channel_count{sink.GetDeviceChannels()}; 361 u32 channel_count{sink.GetDeviceChannels()};
365 362
@@ -371,7 +368,7 @@ private:
371 rb.Push<u32>(channel_count); 368 rb.Push<u32>(channel_count);
372 } 369 }
373 370
374 void QueryAudioDeviceInputEvent(Kernel::HLERequestContext& ctx) { 371 void QueryAudioDeviceInputEvent(HLERequestContext& ctx) {
375 LOG_DEBUG(Service_Audio, "(STUBBED) called"); 372 LOG_DEBUG(Service_Audio, "(STUBBED) called");
376 373
377 IPC::ResponseBuilder rb{ctx, 2, 1}; 374 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -379,7 +376,7 @@ private:
379 rb.PushCopyObjects(event->GetReadableEvent()); 376 rb.PushCopyObjects(event->GetReadableEvent());
380 } 377 }
381 378
382 void QueryAudioDeviceOutputEvent(Kernel::HLERequestContext& ctx) { 379 void QueryAudioDeviceOutputEvent(HLERequestContext& ctx) {
383 LOG_DEBUG(Service_Audio, "called"); 380 LOG_DEBUG(Service_Audio, "called");
384 381
385 IPC::ResponseBuilder rb{ctx, 2, 1}; 382 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -387,7 +384,7 @@ private:
387 rb.PushCopyObjects(event->GetReadableEvent()); 384 rb.PushCopyObjects(event->GetReadableEvent());
388 } 385 }
389 386
390 void ListAudioOutputDeviceName(Kernel::HLERequestContext& ctx) { 387 void ListAudioOutputDeviceName(HLERequestContext& ctx) {
391 const size_t in_count = ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>(); 388 const size_t in_count = ctx.GetWriteBufferNumElements<AudioDevice::AudioDeviceName>();
392 389
393 std::vector<AudioDevice::AudioDeviceName> out_names{}; 390 std::vector<AudioDevice::AudioDeviceName> out_names{};
@@ -421,7 +418,7 @@ private:
421}; 418};
422 419
423AudRenU::AudRenU(Core::System& system_) 420AudRenU::AudRenU(Core::System& system_)
424 : ServiceFramework{system_, "audren:u", ServiceThreadType::CreateNew}, 421 : ServiceFramework{system_, "audren:u"},
425 service_context{system_, "audren:u"}, impl{std::make_unique<Manager>(system_)} { 422 service_context{system_, "audren:u"}, impl{std::make_unique<Manager>(system_)} {
426 // clang-format off 423 // clang-format off
427 static const FunctionInfo functions[] = { 424 static const FunctionInfo functions[] = {
@@ -438,7 +435,7 @@ AudRenU::AudRenU(Core::System& system_)
438 435
439AudRenU::~AudRenU() = default; 436AudRenU::~AudRenU() = default;
440 437
441void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { 438void AudRenU::OpenAudioRenderer(HLERequestContext& ctx) {
442 IPC::RequestParser rp{ctx}; 439 IPC::RequestParser rp{ctx};
443 440
444 AudioCore::AudioRendererParameterInternal params; 441 AudioCore::AudioRendererParameterInternal params;
@@ -451,7 +448,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
451 if (impl->GetSessionCount() + 1 > AudioCore::MaxRendererSessions) { 448 if (impl->GetSessionCount() + 1 > AudioCore::MaxRendererSessions) {
452 LOG_ERROR(Service_Audio, "Too many AudioRenderer sessions open!"); 449 LOG_ERROR(Service_Audio, "Too many AudioRenderer sessions open!");
453 IPC::ResponseBuilder rb{ctx, 2}; 450 IPC::ResponseBuilder rb{ctx, 2};
454 rb.Push(ERR_MAXIMUM_SESSIONS_REACHED); 451 rb.Push(Audio::ResultOutOfSessions);
455 return; 452 return;
456 } 453 }
457 454
@@ -464,7 +461,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
464 if (session_id == -1) { 461 if (session_id == -1) {
465 LOG_ERROR(Service_Audio, "Tried to open a session that's already in use!"); 462 LOG_ERROR(Service_Audio, "Tried to open a session that's already in use!");
466 IPC::ResponseBuilder rb{ctx, 2}; 463 IPC::ResponseBuilder rb{ctx, 2};
467 rb.Push(ERR_MAXIMUM_SESSIONS_REACHED); 464 rb.Push(Audio::ResultOutOfSessions);
468 return; 465 return;
469 } 466 }
470 467
@@ -478,7 +475,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
478 applet_resource_user_id, session_id); 475 applet_resource_user_id, session_id);
479} 476}
480 477
481void AudRenU::GetWorkBufferSize(Kernel::HLERequestContext& ctx) { 478void AudRenU::GetWorkBufferSize(HLERequestContext& ctx) {
482 AudioCore::AudioRendererParameterInternal params; 479 AudioCore::AudioRendererParameterInternal params;
483 480
484 IPC::RequestParser rp{ctx}; 481 IPC::RequestParser rp{ctx};
@@ -509,7 +506,7 @@ void AudRenU::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
509 rb.Push<u64>(size); 506 rb.Push<u64>(size);
510} 507}
511 508
512void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) { 509void AudRenU::GetAudioDeviceService(HLERequestContext& ctx) {
513 IPC::RequestParser rp{ctx}; 510 IPC::RequestParser rp{ctx};
514 511
515 const auto applet_resource_user_id = rp.Pop<u64>(); 512 const auto applet_resource_user_id = rp.Pop<u64>();
@@ -523,11 +520,11 @@ void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) {
523 ::Common::MakeMagic('R', 'E', 'V', '1'), num_audio_devices++); 520 ::Common::MakeMagic('R', 'E', 'V', '1'), num_audio_devices++);
524} 521}
525 522
526void AudRenU::OpenAudioRendererForManualExecution(Kernel::HLERequestContext& ctx) { 523void AudRenU::OpenAudioRendererForManualExecution(HLERequestContext& ctx) {
527 LOG_DEBUG(Service_Audio, "called"); 524 LOG_DEBUG(Service_Audio, "called");
528} 525}
529 526
530void AudRenU::GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx) { 527void AudRenU::GetAudioDeviceServiceWithRevisionInfo(HLERequestContext& ctx) {
531 struct Parameters { 528 struct Parameters {
532 u32 revision; 529 u32 revision;
533 u64 applet_resource_user_id; 530 u64 applet_resource_user_id;
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h
index 4384a9b3c..24ce37e87 100644
--- a/src/core/hle/service/audio/audren_u.h
+++ b/src/core/hle/service/audio/audren_u.h
@@ -11,10 +11,6 @@ namespace Core {
11class System; 11class System;
12} 12}
13 13
14namespace Kernel {
15class HLERequestContext;
16}
17
18namespace Service::Audio { 14namespace Service::Audio {
19class IAudioRenderer; 15class IAudioRenderer;
20 16
@@ -24,11 +20,11 @@ public:
24 ~AudRenU() override; 20 ~AudRenU() override;
25 21
26private: 22private:
27 void OpenAudioRenderer(Kernel::HLERequestContext& ctx); 23 void OpenAudioRenderer(HLERequestContext& ctx);
28 void GetWorkBufferSize(Kernel::HLERequestContext& ctx); 24 void GetWorkBufferSize(HLERequestContext& ctx);
29 void GetAudioDeviceService(Kernel::HLERequestContext& ctx); 25 void GetAudioDeviceService(HLERequestContext& ctx);
30 void OpenAudioRendererForManualExecution(Kernel::HLERequestContext& ctx); 26 void OpenAudioRendererForManualExecution(HLERequestContext& ctx);
31 void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx); 27 void GetAudioDeviceServiceWithRevisionInfo(HLERequestContext& ctx);
32 28
33 KernelHelpers::ServiceContext service_context; 29 KernelHelpers::ServiceContext service_context;
34 std::unique_ptr<AudioCore::AudioRenderer::Manager> impl; 30 std::unique_ptr<AudioCore::AudioRenderer::Manager> impl;
diff --git a/src/core/hle/service/audio/errors.h b/src/core/hle/service/audio/errors.h
index d706978cb..3d3d3d97a 100644
--- a/src/core/hle/service/audio/errors.h
+++ b/src/core/hle/service/audio/errors.h
@@ -7,17 +7,17 @@
7 7
8namespace Service::Audio { 8namespace Service::Audio {
9 9
10constexpr Result ERR_INVALID_DEVICE_NAME{ErrorModule::Audio, 1}; 10constexpr Result ResultNotFound{ErrorModule::Audio, 1};
11constexpr Result ERR_OPERATION_FAILED{ErrorModule::Audio, 2}; 11constexpr Result ResultOperationFailed{ErrorModule::Audio, 2};
12constexpr Result ERR_INVALID_SAMPLE_RATE{ErrorModule::Audio, 3}; 12constexpr Result ResultInvalidSampleRate{ErrorModule::Audio, 3};
13constexpr Result ERR_INSUFFICIENT_BUFFER_SIZE{ErrorModule::Audio, 4}; 13constexpr Result ResultInsufficientBuffer{ErrorModule::Audio, 4};
14constexpr Result ERR_MAXIMUM_SESSIONS_REACHED{ErrorModule::Audio, 5}; 14constexpr Result ResultOutOfSessions{ErrorModule::Audio, 5};
15constexpr Result ERR_BUFFER_COUNT_EXCEEDED{ErrorModule::Audio, 8}; 15constexpr Result ResultBufferCountReached{ErrorModule::Audio, 8};
16constexpr Result ERR_INVALID_CHANNEL_COUNT{ErrorModule::Audio, 10}; 16constexpr Result ResultInvalidChannelCount{ErrorModule::Audio, 10};
17constexpr Result ERR_INVALID_UPDATE_DATA{ErrorModule::Audio, 41}; 17constexpr Result ResultInvalidUpdateInfo{ErrorModule::Audio, 41};
18constexpr Result ERR_POOL_MAPPING_FAILED{ErrorModule::Audio, 42}; 18constexpr Result ResultInvalidAddressInfo{ErrorModule::Audio, 42};
19constexpr Result ERR_NOT_SUPPORTED{ErrorModule::Audio, 513}; 19constexpr Result ResultNotSupported{ErrorModule::Audio, 513};
20constexpr Result ERR_INVALID_PROCESS_HANDLE{ErrorModule::Audio, 1536}; 20constexpr Result ResultInvalidHandle{ErrorModule::Audio, 1536};
21constexpr Result ERR_INVALID_REVISION{ErrorModule::Audio, 1537}; 21constexpr Result ResultInvalidRevision{ErrorModule::Audio, 1537};
22 22
23} // namespace Service::Audio 23} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index 3db3fe188..451ac224a 100644
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -11,8 +11,8 @@
11 11
12#include "common/assert.h" 12#include "common/assert.h"
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "core/hle/ipc_helpers.h"
15#include "core/hle/service/audio/hwopus.h" 14#include "core/hle/service/audio/hwopus.h"
15#include "core/hle/service/ipc_helpers.h"
16 16
17namespace Service::Audio { 17namespace Service::Audio {
18namespace { 18namespace {
@@ -53,7 +53,7 @@ public:
53 53
54 // Decodes interleaved Opus packets. Optionally allows reporting time taken to 54 // Decodes interleaved Opus packets. Optionally allows reporting time taken to
55 // perform the decoding, as well as any relevant extra behavior. 55 // perform the decoding, as well as any relevant extra behavior.
56 void DecodeInterleaved(Kernel::HLERequestContext& ctx, PerfTime perf_time, 56 void DecodeInterleaved(HLERequestContext& ctx, PerfTime perf_time,
57 ExtraBehavior extra_behavior) { 57 ExtraBehavior extra_behavior) {
58 if (perf_time == PerfTime::Disabled) { 58 if (perf_time == PerfTime::Disabled) {
59 DecodeInterleavedHelper(ctx, nullptr, extra_behavior); 59 DecodeInterleavedHelper(ctx, nullptr, extra_behavior);
@@ -64,7 +64,7 @@ public:
64 } 64 }
65 65
66private: 66private:
67 void DecodeInterleavedHelper(Kernel::HLERequestContext& ctx, u64* performance, 67 void DecodeInterleavedHelper(HLERequestContext& ctx, u64* performance,
68 ExtraBehavior extra_behavior) { 68 ExtraBehavior extra_behavior) {
69 u32 consumed = 0; 69 u32 consumed = 0;
70 u32 sample_count = 0; 70 u32 sample_count = 0;
@@ -180,21 +180,21 @@ public:
180 } 180 }
181 181
182private: 182private:
183 void DecodeInterleavedOld(Kernel::HLERequestContext& ctx) { 183 void DecodeInterleavedOld(HLERequestContext& ctx) {
184 LOG_DEBUG(Audio, "called"); 184 LOG_DEBUG(Audio, "called");
185 185
186 decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Disabled, 186 decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Disabled,
187 OpusDecoderState::ExtraBehavior::None); 187 OpusDecoderState::ExtraBehavior::None);
188 } 188 }
189 189
190 void DecodeInterleavedWithPerfOld(Kernel::HLERequestContext& ctx) { 190 void DecodeInterleavedWithPerfOld(HLERequestContext& ctx) {
191 LOG_DEBUG(Audio, "called"); 191 LOG_DEBUG(Audio, "called");
192 192
193 decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Enabled, 193 decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Enabled,
194 OpusDecoderState::ExtraBehavior::None); 194 OpusDecoderState::ExtraBehavior::None);
195 } 195 }
196 196
197 void DecodeInterleaved(Kernel::HLERequestContext& ctx) { 197 void DecodeInterleaved(HLERequestContext& ctx) {
198 LOG_DEBUG(Audio, "called"); 198 LOG_DEBUG(Audio, "called");
199 199
200 IPC::RequestParser rp{ctx}; 200 IPC::RequestParser rp{ctx};
@@ -231,7 +231,7 @@ std::array<u8, 2> CreateMappingTable(u32 channel_count) {
231} 231}
232} // Anonymous namespace 232} // Anonymous namespace
233 233
234void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) { 234void HwOpus::GetWorkBufferSize(HLERequestContext& ctx) {
235 IPC::RequestParser rp{ctx}; 235 IPC::RequestParser rp{ctx};
236 const auto sample_rate = rp.Pop<u32>(); 236 const auto sample_rate = rp.Pop<u32>();
237 const auto channel_count = rp.Pop<u32>(); 237 const auto channel_count = rp.Pop<u32>();
@@ -251,11 +251,11 @@ void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
251 rb.Push<u32>(worker_buffer_sz); 251 rb.Push<u32>(worker_buffer_sz);
252} 252}
253 253
254void HwOpus::GetWorkBufferSizeEx(Kernel::HLERequestContext& ctx) { 254void HwOpus::GetWorkBufferSizeEx(HLERequestContext& ctx) {
255 GetWorkBufferSize(ctx); 255 GetWorkBufferSize(ctx);
256} 256}
257 257
258void HwOpus::GetWorkBufferSizeForMultiStreamEx(Kernel::HLERequestContext& ctx) { 258void HwOpus::GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx) {
259 OpusMultiStreamParametersEx param; 259 OpusMultiStreamParametersEx param;
260 std::memcpy(&param, ctx.ReadBuffer().data(), ctx.GetReadBufferSize()); 260 std::memcpy(&param, ctx.ReadBuffer().data(), ctx.GetReadBufferSize());
261 261
@@ -281,7 +281,7 @@ void HwOpus::GetWorkBufferSizeForMultiStreamEx(Kernel::HLERequestContext& ctx) {
281 rb.Push<u32>(worker_buffer_sz); 281 rb.Push<u32>(worker_buffer_sz);
282} 282}
283 283
284void HwOpus::OpenHardwareOpusDecoder(Kernel::HLERequestContext& ctx) { 284void HwOpus::OpenHardwareOpusDecoder(HLERequestContext& ctx) {
285 IPC::RequestParser rp{ctx}; 285 IPC::RequestParser rp{ctx};
286 const auto sample_rate = rp.Pop<u32>(); 286 const auto sample_rate = rp.Pop<u32>();
287 const auto channel_count = rp.Pop<u32>(); 287 const auto channel_count = rp.Pop<u32>();
@@ -319,7 +319,7 @@ void HwOpus::OpenHardwareOpusDecoder(Kernel::HLERequestContext& ctx) {
319 system, OpusDecoderState{std::move(decoder), sample_rate, channel_count}); 319 system, OpusDecoderState{std::move(decoder), sample_rate, channel_count});
320} 320}
321 321
322void HwOpus::OpenHardwareOpusDecoderEx(Kernel::HLERequestContext& ctx) { 322void HwOpus::OpenHardwareOpusDecoderEx(HLERequestContext& ctx) {
323 IPC::RequestParser rp{ctx}; 323 IPC::RequestParser rp{ctx};
324 const auto sample_rate = rp.Pop<u32>(); 324 const auto sample_rate = rp.Pop<u32>();
325 const auto channel_count = rp.Pop<u32>(); 325 const auto channel_count = rp.Pop<u32>();
diff --git a/src/core/hle/service/audio/hwopus.h b/src/core/hle/service/audio/hwopus.h
index e6092e290..ece65c02c 100644
--- a/src/core/hle/service/audio/hwopus.h
+++ b/src/core/hle/service/audio/hwopus.h
@@ -27,11 +27,11 @@ public:
27 ~HwOpus() override; 27 ~HwOpus() override;
28 28
29private: 29private:
30 void OpenHardwareOpusDecoder(Kernel::HLERequestContext& ctx); 30 void OpenHardwareOpusDecoder(HLERequestContext& ctx);
31 void OpenHardwareOpusDecoderEx(Kernel::HLERequestContext& ctx); 31 void OpenHardwareOpusDecoderEx(HLERequestContext& ctx);
32 void GetWorkBufferSize(Kernel::HLERequestContext& ctx); 32 void GetWorkBufferSize(HLERequestContext& ctx);
33 void GetWorkBufferSizeEx(Kernel::HLERequestContext& ctx); 33 void GetWorkBufferSizeEx(HLERequestContext& ctx);
34 void GetWorkBufferSizeForMultiStreamEx(Kernel::HLERequestContext& ctx); 34 void GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx);
35}; 35};
36 36
37} // namespace Service::Audio 37} // namespace Service::Audio
diff --git a/src/core/hle/service/bcat/bcat_module.cpp b/src/core/hle/service/bcat/bcat_module.cpp
index 6e6fed227..a6281913a 100644
--- a/src/core/hle/service/bcat/bcat_module.cpp
+++ b/src/core/hle/service/bcat/bcat_module.cpp
@@ -9,12 +9,13 @@
9#include "common/string_util.h" 9#include "common/string_util.h"
10#include "core/core.h" 10#include "core/core.h"
11#include "core/file_sys/vfs.h" 11#include "core/file_sys/vfs.h"
12#include "core/hle/ipc_helpers.h"
13#include "core/hle/kernel/k_readable_event.h" 12#include "core/hle/kernel/k_readable_event.h"
14#include "core/hle/service/bcat/backend/backend.h" 13#include "core/hle/service/bcat/backend/backend.h"
15#include "core/hle/service/bcat/bcat.h" 14#include "core/hle/service/bcat/bcat.h"
16#include "core/hle/service/bcat/bcat_module.h" 15#include "core/hle/service/bcat/bcat_module.h"
17#include "core/hle/service/filesystem/filesystem.h" 16#include "core/hle/service/filesystem/filesystem.h"
17#include "core/hle/service/ipc_helpers.h"
18#include "core/hle/service/server_manager.h"
18 19
19namespace Service::BCAT { 20namespace Service::BCAT {
20 21
@@ -50,8 +51,7 @@ BCATDigest DigestFile(const FileSys::VirtualFile& file) {
50// For a name to be valid it must be non-empty, must have a null terminating character as the final 51// For a name to be valid it must be non-empty, must have a null terminating character as the final
51// char, can only contain numbers, letters, underscores and a hyphen if directory and a period if 52// char, can only contain numbers, letters, underscores and a hyphen if directory and a period if
52// file. 53// file.
53bool VerifyNameValidInternal(Kernel::HLERequestContext& ctx, std::array<char, 0x20> name, 54bool VerifyNameValidInternal(HLERequestContext& ctx, std::array<char, 0x20> name, char match_char) {
54 char match_char) {
55 const auto null_chars = std::count(name.begin(), name.end(), 0); 55 const auto null_chars = std::count(name.begin(), name.end(), 0);
56 const auto bad_chars = std::count_if(name.begin(), name.end(), [match_char](char c) { 56 const auto bad_chars = std::count_if(name.begin(), name.end(), [match_char](char c) {
57 return !std::isalnum(static_cast<u8>(c)) && c != '_' && c != match_char && c != '\0'; 57 return !std::isalnum(static_cast<u8>(c)) && c != '_' && c != match_char && c != '\0';
@@ -66,11 +66,11 @@ bool VerifyNameValidInternal(Kernel::HLERequestContext& ctx, std::array<char, 0x
66 return true; 66 return true;
67} 67}
68 68
69bool VerifyNameValidDir(Kernel::HLERequestContext& ctx, DirectoryName name) { 69bool VerifyNameValidDir(HLERequestContext& ctx, DirectoryName name) {
70 return VerifyNameValidInternal(ctx, name, '-'); 70 return VerifyNameValidInternal(ctx, name, '-');
71} 71}
72 72
73bool VerifyNameValidFile(Kernel::HLERequestContext& ctx, FileName name) { 73bool VerifyNameValidFile(HLERequestContext& ctx, FileName name) {
74 return VerifyNameValidInternal(ctx, name, '.'); 74 return VerifyNameValidInternal(ctx, name, '.');
75} 75}
76 76
@@ -98,7 +98,7 @@ public:
98 } 98 }
99 99
100private: 100private:
101 void GetEvent(Kernel::HLERequestContext& ctx) { 101 void GetEvent(HLERequestContext& ctx) {
102 LOG_DEBUG(Service_BCAT, "called"); 102 LOG_DEBUG(Service_BCAT, "called");
103 103
104 IPC::ResponseBuilder rb{ctx, 2, 1}; 104 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -106,7 +106,7 @@ private:
106 rb.PushCopyObjects(event); 106 rb.PushCopyObjects(event);
107 } 107 }
108 108
109 void GetImpl(Kernel::HLERequestContext& ctx) { 109 void GetImpl(HLERequestContext& ctx) {
110 LOG_DEBUG(Service_BCAT, "called"); 110 LOG_DEBUG(Service_BCAT, "called");
111 111
112 ctx.WriteBuffer(impl); 112 ctx.WriteBuffer(impl);
@@ -173,7 +173,7 @@ private:
173 progress_backend.GetImpl()); 173 progress_backend.GetImpl());
174 } 174 }
175 175
176 void RequestSyncDeliveryCache(Kernel::HLERequestContext& ctx) { 176 void RequestSyncDeliveryCache(HLERequestContext& ctx) {
177 LOG_DEBUG(Service_BCAT, "called"); 177 LOG_DEBUG(Service_BCAT, "called");
178 178
179 backend.Synchronize({system.GetApplicationProcessProgramID(), 179 backend.Synchronize({system.GetApplicationProcessProgramID(),
@@ -185,7 +185,7 @@ private:
185 rb.PushIpcInterface(CreateProgressService(SyncType::Normal)); 185 rb.PushIpcInterface(CreateProgressService(SyncType::Normal));
186 } 186 }
187 187
188 void RequestSyncDeliveryCacheWithDirectoryName(Kernel::HLERequestContext& ctx) { 188 void RequestSyncDeliveryCacheWithDirectoryName(HLERequestContext& ctx) {
189 IPC::RequestParser rp{ctx}; 189 IPC::RequestParser rp{ctx};
190 const auto name_raw = rp.PopRaw<DirectoryName>(); 190 const auto name_raw = rp.PopRaw<DirectoryName>();
191 const auto name = 191 const auto name =
@@ -202,7 +202,7 @@ private:
202 rb.PushIpcInterface(CreateProgressService(SyncType::Directory)); 202 rb.PushIpcInterface(CreateProgressService(SyncType::Directory));
203 } 203 }
204 204
205 void SetPassphrase(Kernel::HLERequestContext& ctx) { 205 void SetPassphrase(HLERequestContext& ctx) {
206 IPC::RequestParser rp{ctx}; 206 IPC::RequestParser rp{ctx};
207 const auto title_id = rp.PopRaw<u64>(); 207 const auto title_id = rp.PopRaw<u64>();
208 208
@@ -234,7 +234,7 @@ private:
234 rb.Push(ResultSuccess); 234 rb.Push(ResultSuccess);
235 } 235 }
236 236
237 void ClearDeliveryCacheStorage(Kernel::HLERequestContext& ctx) { 237 void ClearDeliveryCacheStorage(HLERequestContext& ctx) {
238 IPC::RequestParser rp{ctx}; 238 IPC::RequestParser rp{ctx};
239 const auto title_id = rp.PopRaw<u64>(); 239 const auto title_id = rp.PopRaw<u64>();
240 240
@@ -270,7 +270,7 @@ private:
270 std::array<ProgressServiceBackend, static_cast<size_t>(SyncType::Count)> progress; 270 std::array<ProgressServiceBackend, static_cast<size_t>(SyncType::Count)> progress;
271}; 271};
272 272
273void Module::Interface::CreateBcatService(Kernel::HLERequestContext& ctx) { 273void Module::Interface::CreateBcatService(HLERequestContext& ctx) {
274 LOG_DEBUG(Service_BCAT, "called"); 274 LOG_DEBUG(Service_BCAT, "called");
275 275
276 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 276 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -295,7 +295,7 @@ public:
295 } 295 }
296 296
297private: 297private:
298 void Open(Kernel::HLERequestContext& ctx) { 298 void Open(HLERequestContext& ctx) {
299 IPC::RequestParser rp{ctx}; 299 IPC::RequestParser rp{ctx};
300 const auto dir_name_raw = rp.PopRaw<DirectoryName>(); 300 const auto dir_name_raw = rp.PopRaw<DirectoryName>();
301 const auto file_name_raw = rp.PopRaw<FileName>(); 301 const auto file_name_raw = rp.PopRaw<FileName>();
@@ -339,7 +339,7 @@ private:
339 rb.Push(ResultSuccess); 339 rb.Push(ResultSuccess);
340 } 340 }
341 341
342 void Read(Kernel::HLERequestContext& ctx) { 342 void Read(HLERequestContext& ctx) {
343 IPC::RequestParser rp{ctx}; 343 IPC::RequestParser rp{ctx};
344 const auto offset{rp.PopRaw<u64>()}; 344 const auto offset{rp.PopRaw<u64>()};
345 345
@@ -362,7 +362,7 @@ private:
362 rb.Push<u64>(buffer.size()); 362 rb.Push<u64>(buffer.size());
363 } 363 }
364 364
365 void GetSize(Kernel::HLERequestContext& ctx) { 365 void GetSize(HLERequestContext& ctx) {
366 LOG_DEBUG(Service_BCAT, "called"); 366 LOG_DEBUG(Service_BCAT, "called");
367 367
368 if (current_file == nullptr) { 368 if (current_file == nullptr) {
@@ -376,7 +376,7 @@ private:
376 rb.Push<u64>(current_file->GetSize()); 376 rb.Push<u64>(current_file->GetSize());
377 } 377 }
378 378
379 void GetDigest(Kernel::HLERequestContext& ctx) { 379 void GetDigest(HLERequestContext& ctx) {
380 LOG_DEBUG(Service_BCAT, "called"); 380 LOG_DEBUG(Service_BCAT, "called");
381 381
382 if (current_file == nullptr) { 382 if (current_file == nullptr) {
@@ -411,7 +411,7 @@ public:
411 } 411 }
412 412
413private: 413private:
414 void Open(Kernel::HLERequestContext& ctx) { 414 void Open(HLERequestContext& ctx) {
415 IPC::RequestParser rp{ctx}; 415 IPC::RequestParser rp{ctx};
416 const auto name_raw = rp.PopRaw<DirectoryName>(); 416 const auto name_raw = rp.PopRaw<DirectoryName>();
417 const auto name = 417 const auto name =
@@ -442,7 +442,7 @@ private:
442 rb.Push(ResultSuccess); 442 rb.Push(ResultSuccess);
443 } 443 }
444 444
445 void Read(Kernel::HLERequestContext& ctx) { 445 void Read(HLERequestContext& ctx) {
446 auto write_size = ctx.GetWriteBufferNumElements<DeliveryCacheDirectoryEntry>(); 446 auto write_size = ctx.GetWriteBufferNumElements<DeliveryCacheDirectoryEntry>();
447 447
448 LOG_DEBUG(Service_BCAT, "called, write_size={:016X}", write_size); 448 LOG_DEBUG(Service_BCAT, "called, write_size={:016X}", write_size);
@@ -472,7 +472,7 @@ private:
472 rb.Push(static_cast<u32>(write_size * sizeof(DeliveryCacheDirectoryEntry))); 472 rb.Push(static_cast<u32>(write_size * sizeof(DeliveryCacheDirectoryEntry)));
473 } 473 }
474 474
475 void GetCount(Kernel::HLERequestContext& ctx) { 475 void GetCount(HLERequestContext& ctx) {
476 LOG_DEBUG(Service_BCAT, "called"); 476 LOG_DEBUG(Service_BCAT, "called");
477 477
478 if (current_dir == nullptr) { 478 if (current_dir == nullptr) {
@@ -516,7 +516,7 @@ public:
516 } 516 }
517 517
518private: 518private:
519 void CreateFileService(Kernel::HLERequestContext& ctx) { 519 void CreateFileService(HLERequestContext& ctx) {
520 LOG_DEBUG(Service_BCAT, "called"); 520 LOG_DEBUG(Service_BCAT, "called");
521 521
522 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 522 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -524,7 +524,7 @@ private:
524 rb.PushIpcInterface<IDeliveryCacheFileService>(system, root); 524 rb.PushIpcInterface<IDeliveryCacheFileService>(system, root);
525 } 525 }
526 526
527 void CreateDirectoryService(Kernel::HLERequestContext& ctx) { 527 void CreateDirectoryService(HLERequestContext& ctx) {
528 LOG_DEBUG(Service_BCAT, "called"); 528 LOG_DEBUG(Service_BCAT, "called");
529 529
530 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 530 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -532,7 +532,7 @@ private:
532 rb.PushIpcInterface<IDeliveryCacheDirectoryService>(system, root); 532 rb.PushIpcInterface<IDeliveryCacheDirectoryService>(system, root);
533 } 533 }
534 534
535 void EnumerateDeliveryCacheDirectory(Kernel::HLERequestContext& ctx) { 535 void EnumerateDeliveryCacheDirectory(HLERequestContext& ctx) {
536 auto size = ctx.GetWriteBufferNumElements<DirectoryName>(); 536 auto size = ctx.GetWriteBufferNumElements<DirectoryName>();
537 537
538 LOG_DEBUG(Service_BCAT, "called, size={:016X}", size); 538 LOG_DEBUG(Service_BCAT, "called, size={:016X}", size);
@@ -551,7 +551,7 @@ private:
551 u64 next_read_index = 0; 551 u64 next_read_index = 0;
552}; 552};
553 553
554void Module::Interface::CreateDeliveryCacheStorageService(Kernel::HLERequestContext& ctx) { 554void Module::Interface::CreateDeliveryCacheStorageService(HLERequestContext& ctx) {
555 LOG_DEBUG(Service_BCAT, "called"); 555 LOG_DEBUG(Service_BCAT, "called");
556 556
557 const auto title_id = system.GetApplicationProcessProgramID(); 557 const auto title_id = system.GetApplicationProcessProgramID();
@@ -560,8 +560,7 @@ void Module::Interface::CreateDeliveryCacheStorageService(Kernel::HLERequestCont
560 rb.PushIpcInterface<IDeliveryCacheStorageService>(system, fsc.GetBCATDirectory(title_id)); 560 rb.PushIpcInterface<IDeliveryCacheStorageService>(system, fsc.GetBCATDirectory(title_id));
561} 561}
562 562
563void Module::Interface::CreateDeliveryCacheStorageServiceWithApplicationId( 563void Module::Interface::CreateDeliveryCacheStorageServiceWithApplicationId(HLERequestContext& ctx) {
564 Kernel::HLERequestContext& ctx) {
565 IPC::RequestParser rp{ctx}; 564 IPC::RequestParser rp{ctx};
566 const auto title_id = rp.PopRaw<u64>(); 565 const auto title_id = rp.PopRaw<u64>();
567 566
@@ -585,16 +584,23 @@ Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> modu
585 584
586Module::Interface::~Interface() = default; 585Module::Interface::~Interface() = default;
587 586
588void InstallInterfaces(Core::System& system) { 587void LoopProcess(Core::System& system) {
588 auto server_manager = std::make_unique<ServerManager>(system);
589 auto module = std::make_shared<Module>(); 589 auto module = std::make_shared<Module>();
590 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:a") 590
591 ->InstallAsService(system.ServiceManager()); 591 server_manager->RegisterNamedService(
592 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:m") 592 "bcat:a",
593 ->InstallAsService(system.ServiceManager()); 593 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:a"));
594 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:u") 594 server_manager->RegisterNamedService(
595 ->InstallAsService(system.ServiceManager()); 595 "bcat:m",
596 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:s") 596 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:m"));
597 ->InstallAsService(system.ServiceManager()); 597 server_manager->RegisterNamedService(
598 "bcat:u",
599 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:u"));
600 server_manager->RegisterNamedService(
601 "bcat:s",
602 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:s"));
603 ServerManager::RunServer(std::move(server_manager));
598} 604}
599 605
600} // namespace Service::BCAT 606} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/bcat_module.h b/src/core/hle/service/bcat/bcat_module.h
index b2fcf9bfb..87576288b 100644
--- a/src/core/hle/service/bcat/bcat_module.h
+++ b/src/core/hle/service/bcat/bcat_module.h
@@ -27,9 +27,9 @@ public:
27 FileSystem::FileSystemController& fsc_, const char* name); 27 FileSystem::FileSystemController& fsc_, const char* name);
28 ~Interface() override; 28 ~Interface() override;
29 29
30 void CreateBcatService(Kernel::HLERequestContext& ctx); 30 void CreateBcatService(HLERequestContext& ctx);
31 void CreateDeliveryCacheStorageService(Kernel::HLERequestContext& ctx); 31 void CreateDeliveryCacheStorageService(HLERequestContext& ctx);
32 void CreateDeliveryCacheStorageServiceWithApplicationId(Kernel::HLERequestContext& ctx); 32 void CreateDeliveryCacheStorageServiceWithApplicationId(HLERequestContext& ctx);
33 33
34 protected: 34 protected:
35 FileSystem::FileSystemController& fsc; 35 FileSystem::FileSystemController& fsc;
@@ -39,8 +39,7 @@ public:
39 }; 39 };
40}; 40};
41 41
42/// Registers all BCAT services with the specified service manager. 42void LoopProcess(Core::System& system);
43void InstallInterfaces(Core::System& system);
44 43
45} // namespace BCAT 44} // namespace BCAT
46 45
diff --git a/src/core/hle/service/bpc/bpc.cpp b/src/core/hle/service/bpc/bpc.cpp
index 466163538..91b15e256 100644
--- a/src/core/hle/service/bpc/bpc.cpp
+++ b/src/core/hle/service/bpc/bpc.cpp
@@ -4,8 +4,8 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/bpc/bpc.h" 6#include "core/hle/service/bpc/bpc.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::BPC { 10namespace Service::BPC {
11 11
@@ -54,9 +54,12 @@ public:
54 } 54 }
55}; 55};
56 56
57void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 57void LoopProcess(Core::System& system) {
58 std::make_shared<BPC>(system)->InstallAsService(sm); 58 auto server_manager = std::make_unique<ServerManager>(system);
59 std::make_shared<BPC_R>(system)->InstallAsService(sm); 59
60 server_manager->RegisterNamedService("bpc", std::make_shared<BPC>(system));
61 server_manager->RegisterNamedService("bpc:r", std::make_shared<BPC_R>(system));
62 ServerManager::RunServer(std::move(server_manager));
60} 63}
61 64
62} // namespace Service::BPC 65} // namespace Service::BPC
diff --git a/src/core/hle/service/bpc/bpc.h b/src/core/hle/service/bpc/bpc.h
index 8adc2f962..524391ddb 100644
--- a/src/core/hle/service/bpc/bpc.h
+++ b/src/core/hle/service/bpc/bpc.h
@@ -13,6 +13,6 @@ class ServiceManager;
13 13
14namespace Service::BPC { 14namespace Service::BPC {
15 15
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 16void LoopProcess(Core::System& system);
17 17
18} // namespace Service::BPC 18} // namespace Service::BPC
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp
index ec7e5320c..38cdd57ad 100644
--- a/src/core/hle/service/btdrv/btdrv.cpp
+++ b/src/core/hle/service/btdrv/btdrv.cpp
@@ -3,10 +3,11 @@
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/ipc_helpers.h"
7#include "core/hle/kernel/k_event.h" 6#include "core/hle/kernel/k_event.h"
8#include "core/hle/service/btdrv/btdrv.h" 7#include "core/hle/service/btdrv/btdrv.h"
8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/kernel_helpers.h" 9#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/server_manager.h"
10#include "core/hle/service/service.h" 11#include "core/hle/service/service.h"
11#include "core/hle/service/sm/sm.h" 12#include "core/hle/service/sm/sm.h"
12 13
@@ -40,7 +41,7 @@ public:
40 } 41 }
41 42
42private: 43private:
43 void RegisterBleEvent(Kernel::HLERequestContext& ctx) { 44 void RegisterBleEvent(HLERequestContext& ctx) {
44 LOG_WARNING(Service_BTM, "(STUBBED) called"); 45 LOG_WARNING(Service_BTM, "(STUBBED) called");
45 46
46 IPC::ResponseBuilder rb{ctx, 2, 1}; 47 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -196,9 +197,12 @@ public:
196 } 197 }
197}; 198};
198 199
199void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 200void LoopProcess(Core::System& system) {
200 std::make_shared<BtDrv>(system)->InstallAsService(sm); 201 auto server_manager = std::make_unique<ServerManager>(system);
201 std::make_shared<Bt>(system)->InstallAsService(sm); 202
203 server_manager->RegisterNamedService("btdrv", std::make_shared<BtDrv>(system));
204 server_manager->RegisterNamedService("bt", std::make_shared<Bt>(system));
205 ServerManager::RunServer(std::move(server_manager));
202} 206}
203 207
204} // namespace Service::BtDrv 208} // namespace Service::BtDrv
diff --git a/src/core/hle/service/btdrv/btdrv.h b/src/core/hle/service/btdrv/btdrv.h
index 9cbe2926f..42713860e 100644
--- a/src/core/hle/service/btdrv/btdrv.h
+++ b/src/core/hle/service/btdrv/btdrv.h
@@ -13,7 +13,6 @@ class System;
13 13
14namespace Service::BtDrv { 14namespace Service::BtDrv {
15 15
16/// Registers all BtDrv services with the specified service manager. 16void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
18 17
19} // namespace Service::BtDrv 18} // namespace Service::BtDrv
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index eebf85e03..8069f75b7 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -5,10 +5,11 @@
5 5
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core.h" 7#include "core/core.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/k_event.h" 8#include "core/hle/kernel/k_event.h"
10#include "core/hle/service/btm/btm.h" 9#include "core/hle/service/btm/btm.h"
10#include "core/hle/service/ipc_helpers.h"
11#include "core/hle/service/kernel_helpers.h" 11#include "core/hle/service/kernel_helpers.h"
12#include "core/hle/service/server_manager.h"
12#include "core/hle/service/service.h" 13#include "core/hle/service/service.h"
13 14
14namespace Service::BTM { 15namespace Service::BTM {
@@ -69,35 +70,39 @@ public:
69 } 70 }
70 71
71private: 72private:
72 void AcquireBleScanEvent(Kernel::HLERequestContext& ctx) { 73 void AcquireBleScanEvent(HLERequestContext& ctx) {
73 LOG_WARNING(Service_BTM, "(STUBBED) called"); 74 LOG_WARNING(Service_BTM, "(STUBBED) called");
74 75
75 IPC::ResponseBuilder rb{ctx, 2, 1}; 76 IPC::ResponseBuilder rb{ctx, 3, 1};
76 rb.Push(ResultSuccess); 77 rb.Push(ResultSuccess);
78 rb.Push(true);
77 rb.PushCopyObjects(scan_event->GetReadableEvent()); 79 rb.PushCopyObjects(scan_event->GetReadableEvent());
78 } 80 }
79 81
80 void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) { 82 void AcquireBleConnectionEvent(HLERequestContext& ctx) {
81 LOG_WARNING(Service_BTM, "(STUBBED) called"); 83 LOG_WARNING(Service_BTM, "(STUBBED) called");
82 84
83 IPC::ResponseBuilder rb{ctx, 2, 1}; 85 IPC::ResponseBuilder rb{ctx, 3, 1};
84 rb.Push(ResultSuccess); 86 rb.Push(ResultSuccess);
87 rb.Push(true);
85 rb.PushCopyObjects(connection_event->GetReadableEvent()); 88 rb.PushCopyObjects(connection_event->GetReadableEvent());
86 } 89 }
87 90
88 void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) { 91 void AcquireBleServiceDiscoveryEvent(HLERequestContext& ctx) {
89 LOG_WARNING(Service_BTM, "(STUBBED) called"); 92 LOG_WARNING(Service_BTM, "(STUBBED) called");
90 93
91 IPC::ResponseBuilder rb{ctx, 2, 1}; 94 IPC::ResponseBuilder rb{ctx, 3, 1};
92 rb.Push(ResultSuccess); 95 rb.Push(ResultSuccess);
96 rb.Push(true);
93 rb.PushCopyObjects(service_discovery_event->GetReadableEvent()); 97 rb.PushCopyObjects(service_discovery_event->GetReadableEvent());
94 } 98 }
95 99
96 void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) { 100 void AcquireBleMtuConfigEvent(HLERequestContext& ctx) {
97 LOG_WARNING(Service_BTM, "(STUBBED) called"); 101 LOG_WARNING(Service_BTM, "(STUBBED) called");
98 102
99 IPC::ResponseBuilder rb{ctx, 2, 1}; 103 IPC::ResponseBuilder rb{ctx, 3, 1};
100 rb.Push(ResultSuccess); 104 rb.Push(ResultSuccess);
105 rb.Push(true);
101 rb.PushCopyObjects(config_event->GetReadableEvent()); 106 rb.PushCopyObjects(config_event->GetReadableEvent());
102 } 107 }
103 108
@@ -121,7 +126,7 @@ public:
121 } 126 }
122 127
123private: 128private:
124 void GetCore(Kernel::HLERequestContext& ctx) { 129 void GetCore(HLERequestContext& ctx) {
125 LOG_DEBUG(Service_BTM, "called"); 130 LOG_DEBUG(Service_BTM, "called");
126 131
127 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 132 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -302,7 +307,7 @@ public:
302 } 307 }
303 308
304private: 309private:
305 void GetCore(Kernel::HLERequestContext& ctx) { 310 void GetCore(HLERequestContext& ctx) {
306 LOG_DEBUG(Service_BTM, "called"); 311 LOG_DEBUG(Service_BTM, "called");
307 312
308 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 313 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -311,11 +316,14 @@ private:
311 } 316 }
312}; 317};
313 318
314void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 319void LoopProcess(Core::System& system) {
315 std::make_shared<BTM>(system)->InstallAsService(sm); 320 auto server_manager = std::make_unique<ServerManager>(system);
316 std::make_shared<BTM_DBG>(system)->InstallAsService(sm); 321
317 std::make_shared<BTM_SYS>(system)->InstallAsService(sm); 322 server_manager->RegisterNamedService("btm", std::make_shared<BTM>(system));
318 std::make_shared<BTM_USR>(system)->InstallAsService(sm); 323 server_manager->RegisterNamedService("btm:dbg", std::make_shared<BTM_DBG>(system));
324 server_manager->RegisterNamedService("btm:sys", std::make_shared<BTM_SYS>(system));
325 server_manager->RegisterNamedService("btm:u", std::make_shared<BTM_USR>(system));
326 ServerManager::RunServer(std::move(server_manager));
319} 327}
320 328
321} // namespace Service::BTM 329} // namespace Service::BTM
diff --git a/src/core/hle/service/btm/btm.h b/src/core/hle/service/btm/btm.h
index 9dcda1848..a99b34364 100644
--- a/src/core/hle/service/btm/btm.h
+++ b/src/core/hle/service/btm/btm.h
@@ -13,6 +13,6 @@ class System;
13 13
14namespace Service::BTM { 14namespace Service::BTM {
15 15
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 16void LoopProcess(Core::System& system);
17 17
18} // namespace Service::BTM 18} // namespace Service::BTM
diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp
index 13940a8c9..610fe9940 100644
--- a/src/core/hle/service/caps/caps.cpp
+++ b/src/core/hle/service/caps/caps.cpp
@@ -8,17 +8,21 @@
8#include "core/hle/service/caps/caps_ss.h" 8#include "core/hle/service/caps/caps_ss.h"
9#include "core/hle/service/caps/caps_su.h" 9#include "core/hle/service/caps/caps_su.h"
10#include "core/hle/service/caps/caps_u.h" 10#include "core/hle/service/caps/caps_u.h"
11#include "core/hle/service/server_manager.h"
11#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
12 13
13namespace Service::Capture { 14namespace Service::Capture {
14 15
15void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 16void LoopProcess(Core::System& system) {
16 std::make_shared<CAPS_A>(system)->InstallAsService(sm); 17 auto server_manager = std::make_unique<ServerManager>(system);
17 std::make_shared<CAPS_C>(system)->InstallAsService(sm); 18
18 std::make_shared<CAPS_U>(system)->InstallAsService(sm); 19 server_manager->RegisterNamedService("caps:a", std::make_shared<CAPS_A>(system));
19 std::make_shared<CAPS_SC>(system)->InstallAsService(sm); 20 server_manager->RegisterNamedService("caps:c", std::make_shared<CAPS_C>(system));
20 std::make_shared<CAPS_SS>(system)->InstallAsService(sm); 21 server_manager->RegisterNamedService("caps:u", std::make_shared<CAPS_U>(system));
21 std::make_shared<CAPS_SU>(system)->InstallAsService(sm); 22 server_manager->RegisterNamedService("caps:sc", std::make_shared<CAPS_SC>(system));
23 server_manager->RegisterNamedService("caps:ss", std::make_shared<CAPS_SS>(system));
24 server_manager->RegisterNamedService("caps:su", std::make_shared<CAPS_SU>(system));
25 ServerManager::RunServer(std::move(server_manager));
22} 26}
23 27
24} // namespace Service::Capture 28} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps.h b/src/core/hle/service/caps/caps.h
index 3e89c82cb..15f0ecfaa 100644
--- a/src/core/hle/service/caps/caps.h
+++ b/src/core/hle/service/caps/caps.h
@@ -90,7 +90,6 @@ struct ApplicationAlbumFileEntry {
90static_assert(sizeof(ApplicationAlbumFileEntry) == 0x30, 90static_assert(sizeof(ApplicationAlbumFileEntry) == 0x30,
91 "ApplicationAlbumFileEntry has incorrect size."); 91 "ApplicationAlbumFileEntry has incorrect size.");
92 92
93/// Registers all Capture services with the specified service manager. 93void LoopProcess(Core::System& system);
94void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
95 94
96} // namespace Service::Capture 95} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_a.h b/src/core/hle/service/caps/caps_a.h
index 319c173d8..98a21a5ad 100644
--- a/src/core/hle/service/caps/caps_a.h
+++ b/src/core/hle/service/caps/caps_a.h
@@ -9,10 +9,6 @@ namespace Core {
9class System; 9class System;
10} 10}
11 11
12namespace Kernel {
13class HLERequestContext;
14}
15
16namespace Service::Capture { 12namespace Service::Capture {
17 13
18class CAPS_A final : public ServiceFramework<CAPS_A> { 14class CAPS_A final : public ServiceFramework<CAPS_A> {
diff --git a/src/core/hle/service/caps/caps_c.cpp b/src/core/hle/service/caps/caps_c.cpp
index 725a2e3a7..fc77e35cd 100644
--- a/src/core/hle/service/caps/caps_c.cpp
+++ b/src/core/hle/service/caps/caps_c.cpp
@@ -2,8 +2,8 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/caps/caps_c.h" 5#include "core/hle/service/caps/caps_c.h"
6#include "core/hle/service/ipc_helpers.h"
7 7
8namespace Service::Capture { 8namespace Service::Capture {
9 9
@@ -74,7 +74,7 @@ CAPS_C::CAPS_C(Core::System& system_) : ServiceFramework{system_, "caps:c"} {
74 74
75CAPS_C::~CAPS_C() = default; 75CAPS_C::~CAPS_C() = default;
76 76
77void CAPS_C::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) { 77void CAPS_C::SetShimLibraryVersion(HLERequestContext& ctx) {
78 IPC::RequestParser rp{ctx}; 78 IPC::RequestParser rp{ctx};
79 const auto library_version{rp.Pop<u64>()}; 79 const auto library_version{rp.Pop<u64>()};
80 const auto applet_resource_user_id{rp.Pop<u64>()}; 80 const auto applet_resource_user_id{rp.Pop<u64>()};
diff --git a/src/core/hle/service/caps/caps_c.h b/src/core/hle/service/caps/caps_c.h
index 983a4212d..537b3a2e3 100644
--- a/src/core/hle/service/caps/caps_c.h
+++ b/src/core/hle/service/caps/caps_c.h
@@ -9,10 +9,6 @@ namespace Core {
9class System; 9class System;
10} 10}
11 11
12namespace Kernel {
13class HLERequestContext;
14}
15
16namespace Service::Capture { 12namespace Service::Capture {
17 13
18class CAPS_C final : public ServiceFramework<CAPS_C> { 14class CAPS_C final : public ServiceFramework<CAPS_C> {
@@ -21,7 +17,7 @@ public:
21 ~CAPS_C() override; 17 ~CAPS_C() override;
22 18
23private: 19private:
24 void SetShimLibraryVersion(Kernel::HLERequestContext& ctx); 20 void SetShimLibraryVersion(HLERequestContext& ctx);
25}; 21};
26 22
27} // namespace Service::Capture 23} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp
index fcb496756..3b11cc95c 100644
--- a/src/core/hle/service/caps/caps_su.cpp
+++ b/src/core/hle/service/caps/caps_su.cpp
@@ -2,8 +2,8 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/caps/caps_su.h" 5#include "core/hle/service/caps/caps_su.h"
6#include "core/hle/service/ipc_helpers.h"
7 7
8namespace Service::Capture { 8namespace Service::Capture {
9 9
@@ -23,7 +23,7 @@ CAPS_SU::CAPS_SU(Core::System& system_) : ServiceFramework{system_, "caps:su"} {
23 23
24CAPS_SU::~CAPS_SU() = default; 24CAPS_SU::~CAPS_SU() = default;
25 25
26void CAPS_SU::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) { 26void CAPS_SU::SetShimLibraryVersion(HLERequestContext& ctx) {
27 IPC::RequestParser rp{ctx}; 27 IPC::RequestParser rp{ctx};
28 const auto library_version{rp.Pop<u64>()}; 28 const auto library_version{rp.Pop<u64>()};
29 const auto applet_resource_user_id{rp.Pop<u64>()}; 29 const auto applet_resource_user_id{rp.Pop<u64>()};
diff --git a/src/core/hle/service/caps/caps_su.h b/src/core/hle/service/caps/caps_su.h
index c9a1d507b..c6398858d 100644
--- a/src/core/hle/service/caps/caps_su.h
+++ b/src/core/hle/service/caps/caps_su.h
@@ -9,10 +9,6 @@ namespace Core {
9class System; 9class System;
10} 10}
11 11
12namespace Kernel {
13class HLERequestContext;
14}
15
16namespace Service::Capture { 12namespace Service::Capture {
17 13
18class CAPS_SU final : public ServiceFramework<CAPS_SU> { 14class CAPS_SU final : public ServiceFramework<CAPS_SU> {
@@ -21,7 +17,7 @@ public:
21 ~CAPS_SU() override; 17 ~CAPS_SU() override;
22 18
23private: 19private:
24 void SetShimLibraryVersion(Kernel::HLERequestContext& ctx); 20 void SetShimLibraryVersion(HLERequestContext& ctx);
25}; 21};
26 22
27} // namespace Service::Capture 23} // namespace Service::Capture
diff --git a/src/core/hle/service/caps/caps_u.cpp b/src/core/hle/service/caps/caps_u.cpp
index 5fbba8673..bffe0f8d0 100644
--- a/src/core/hle/service/caps/caps_u.cpp
+++ b/src/core/hle/service/caps/caps_u.cpp
@@ -2,9 +2,9 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/caps/caps.h" 5#include "core/hle/service/caps/caps.h"
7#include "core/hle/service/caps/caps_u.h" 6#include "core/hle/service/caps/caps_u.h"
7#include "core/hle/service/ipc_helpers.h"
8 8
9namespace Service::Capture { 9namespace Service::Capture {
10 10
@@ -52,7 +52,7 @@ CAPS_U::CAPS_U(Core::System& system_) : ServiceFramework{system_, "caps:u"} {
52 52
53CAPS_U::~CAPS_U() = default; 53CAPS_U::~CAPS_U() = default;
54 54
55void CAPS_U::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) { 55void CAPS_U::SetShimLibraryVersion(HLERequestContext& ctx) {
56 IPC::RequestParser rp{ctx}; 56 IPC::RequestParser rp{ctx};
57 const auto library_version{rp.Pop<u64>()}; 57 const auto library_version{rp.Pop<u64>()};
58 const auto applet_resource_user_id{rp.Pop<u64>()}; 58 const auto applet_resource_user_id{rp.Pop<u64>()};
@@ -64,7 +64,7 @@ void CAPS_U::SetShimLibraryVersion(Kernel::HLERequestContext& ctx) {
64 rb.Push(ResultSuccess); 64 rb.Push(ResultSuccess);
65} 65}
66 66
67void CAPS_U::GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& ctx) { 67void CAPS_U::GetAlbumContentsFileListForApplication(HLERequestContext& ctx) {
68 // Takes a type-0x6 output buffer containing an array of ApplicationAlbumFileEntry, a PID, an 68 // Takes a type-0x6 output buffer containing an array of ApplicationAlbumFileEntry, a PID, an
69 // u8 ContentType, two s64s, and an u64 AppletResourceUserId. Returns an output u64 for total 69 // u8 ContentType, two s64s, and an u64 AppletResourceUserId. Returns an output u64 for total
70 // output entries (which is copied to a s32 by official SW). 70 // output entries (which is copied to a s32 by official SW).
@@ -93,7 +93,7 @@ void CAPS_U::GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& c
93 rb.Push(total_entries_2); 93 rb.Push(total_entries_2);
94} 94}
95 95
96void CAPS_U::GetAlbumFileList3AaeAruid(Kernel::HLERequestContext& ctx) { 96void CAPS_U::GetAlbumFileList3AaeAruid(HLERequestContext& ctx) {
97 GetAlbumContentsFileListForApplication(ctx); 97 GetAlbumContentsFileListForApplication(ctx);
98} 98}
99 99
diff --git a/src/core/hle/service/caps/caps_u.h b/src/core/hle/service/caps/caps_u.h
index c3d4b9cea..e8dd037d7 100644
--- a/src/core/hle/service/caps/caps_u.h
+++ b/src/core/hle/service/caps/caps_u.h
@@ -9,10 +9,6 @@ namespace Core {
9class System; 9class System;
10} 10}
11 11
12namespace Kernel {
13class HLERequestContext;
14}
15
16namespace Service::Capture { 12namespace Service::Capture {
17 13
18class CAPS_U final : public ServiceFramework<CAPS_U> { 14class CAPS_U final : public ServiceFramework<CAPS_U> {
@@ -21,9 +17,9 @@ public:
21 ~CAPS_U() override; 17 ~CAPS_U() override;
22 18
23private: 19private:
24 void SetShimLibraryVersion(Kernel::HLERequestContext& ctx); 20 void SetShimLibraryVersion(HLERequestContext& ctx);
25 void GetAlbumContentsFileListForApplication(Kernel::HLERequestContext& ctx); 21 void GetAlbumContentsFileListForApplication(HLERequestContext& ctx);
26 void GetAlbumFileList3AaeAruid(Kernel::HLERequestContext& ctx); 22 void GetAlbumFileList3AaeAruid(HLERequestContext& ctx);
27}; 23};
28 24
29} // namespace Service::Capture 25} // namespace Service::Capture
diff --git a/src/core/hle/service/erpt/erpt.cpp b/src/core/hle/service/erpt/erpt.cpp
index 923c0022a..3ea862fad 100644
--- a/src/core/hle/service/erpt/erpt.cpp
+++ b/src/core/hle/service/erpt/erpt.cpp
@@ -4,6 +4,7 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/erpt/erpt.h" 6#include "core/hle/service/erpt/erpt.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h" 9#include "core/hle/service/sm/sm.h"
9 10
@@ -52,9 +53,13 @@ public:
52 } 53 }
53}; 54};
54 55
55void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 56void LoopProcess(Core::System& system) {
56 std::make_shared<ErrorReportContext>(system)->InstallAsService(sm); 57 auto server_manager = std::make_unique<ServerManager>(system);
57 std::make_shared<ErrorReportSession>(system)->InstallAsService(sm); 58
59 server_manager->RegisterNamedService("erpt:c", std::make_shared<ErrorReportContext>(system));
60 server_manager->RegisterNamedService("erpt:r", std::make_shared<ErrorReportSession>(system));
61
62 ServerManager::RunServer(std::move(server_manager));
58} 63}
59 64
60} // namespace Service::ERPT 65} // namespace Service::ERPT
diff --git a/src/core/hle/service/erpt/erpt.h b/src/core/hle/service/erpt/erpt.h
index 507d626ec..60094f556 100644
--- a/src/core/hle/service/erpt/erpt.h
+++ b/src/core/hle/service/erpt/erpt.h
@@ -7,13 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::ERPT { 10namespace Service::ERPT {
15 11
16/// Registers all ERPT services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
18 13
19} // namespace Service::ERPT 14} // namespace Service::ERPT
diff --git a/src/core/hle/service/es/es.cpp b/src/core/hle/service/es/es.cpp
index fb8686859..446f46b3c 100644
--- a/src/core/hle/service/es/es.cpp
+++ b/src/core/hle/service/es/es.cpp
@@ -2,8 +2,9 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/crypto/key_manager.h" 4#include "core/crypto/key_manager.h"
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/es/es.h" 5#include "core/hle/service/es/es.h"
6#include "core/hle/service/ipc_helpers.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8 9
9namespace Service::ES { 10namespace Service::ES {
@@ -109,7 +110,7 @@ public:
109 } 110 }
110 111
111private: 112private:
112 bool CheckRightsId(Kernel::HLERequestContext& ctx, const u128& rights_id) { 113 bool CheckRightsId(HLERequestContext& ctx, const u128& rights_id) {
113 if (rights_id == u128{}) { 114 if (rights_id == u128{}) {
114 LOG_ERROR(Service_ETicket, "The rights ID was invalid!"); 115 LOG_ERROR(Service_ETicket, "The rights ID was invalid!");
115 IPC::ResponseBuilder rb{ctx, 2}; 116 IPC::ResponseBuilder rb{ctx, 2};
@@ -120,7 +121,7 @@ private:
120 return true; 121 return true;
121 } 122 }
122 123
123 void ImportTicket(Kernel::HLERequestContext& ctx) { 124 void ImportTicket(HLERequestContext& ctx) {
124 const auto ticket = ctx.ReadBuffer(); 125 const auto ticket = ctx.ReadBuffer();
125 [[maybe_unused]] const auto cert = ctx.ReadBuffer(1); 126 [[maybe_unused]] const auto cert = ctx.ReadBuffer(1);
126 127
@@ -145,7 +146,7 @@ private:
145 rb.Push(ResultSuccess); 146 rb.Push(ResultSuccess);
146 } 147 }
147 148
148 void GetTitleKey(Kernel::HLERequestContext& ctx) { 149 void GetTitleKey(HLERequestContext& ctx) {
149 IPC::RequestParser rp{ctx}; 150 IPC::RequestParser rp{ctx};
150 const auto rights_id = rp.PopRaw<u128>(); 151 const auto rights_id = rp.PopRaw<u128>();
151 152
@@ -171,7 +172,7 @@ private:
171 rb.Push(ResultSuccess); 172 rb.Push(ResultSuccess);
172 } 173 }
173 174
174 void CountCommonTicket(Kernel::HLERequestContext& ctx) { 175 void CountCommonTicket(HLERequestContext& ctx) {
175 LOG_DEBUG(Service_ETicket, "called"); 176 LOG_DEBUG(Service_ETicket, "called");
176 177
177 const u32 count = static_cast<u32>(keys.GetCommonTickets().size()); 178 const u32 count = static_cast<u32>(keys.GetCommonTickets().size());
@@ -181,7 +182,7 @@ private:
181 rb.Push<u32>(count); 182 rb.Push<u32>(count);
182 } 183 }
183 184
184 void CountPersonalizedTicket(Kernel::HLERequestContext& ctx) { 185 void CountPersonalizedTicket(HLERequestContext& ctx) {
185 LOG_DEBUG(Service_ETicket, "called"); 186 LOG_DEBUG(Service_ETicket, "called");
186 187
187 const u32 count = static_cast<u32>(keys.GetPersonalizedTickets().size()); 188 const u32 count = static_cast<u32>(keys.GetPersonalizedTickets().size());
@@ -191,7 +192,7 @@ private:
191 rb.Push<u32>(count); 192 rb.Push<u32>(count);
192 } 193 }
193 194
194 void ListCommonTicketRightsIds(Kernel::HLERequestContext& ctx) { 195 void ListCommonTicketRightsIds(HLERequestContext& ctx) {
195 size_t out_entries = 0; 196 size_t out_entries = 0;
196 if (!keys.GetCommonTickets().empty()) { 197 if (!keys.GetCommonTickets().empty()) {
197 out_entries = ctx.GetWriteBufferNumElements<u128>(); 198 out_entries = ctx.GetWriteBufferNumElements<u128>();
@@ -212,7 +213,7 @@ private:
212 rb.Push<u32>(static_cast<u32>(out_entries)); 213 rb.Push<u32>(static_cast<u32>(out_entries));
213 } 214 }
214 215
215 void ListPersonalizedTicketRightsIds(Kernel::HLERequestContext& ctx) { 216 void ListPersonalizedTicketRightsIds(HLERequestContext& ctx) {
216 size_t out_entries = 0; 217 size_t out_entries = 0;
217 if (!keys.GetPersonalizedTickets().empty()) { 218 if (!keys.GetPersonalizedTickets().empty()) {
218 out_entries = ctx.GetWriteBufferNumElements<u128>(); 219 out_entries = ctx.GetWriteBufferNumElements<u128>();
@@ -234,7 +235,7 @@ private:
234 rb.Push<u32>(static_cast<u32>(out_entries)); 235 rb.Push<u32>(static_cast<u32>(out_entries));
235 } 236 }
236 237
237 void GetCommonTicketSize(Kernel::HLERequestContext& ctx) { 238 void GetCommonTicketSize(HLERequestContext& ctx) {
238 IPC::RequestParser rp{ctx}; 239 IPC::RequestParser rp{ctx};
239 const auto rights_id = rp.PopRaw<u128>(); 240 const auto rights_id = rp.PopRaw<u128>();
240 241
@@ -250,7 +251,7 @@ private:
250 rb.Push<u64>(ticket.GetSize()); 251 rb.Push<u64>(ticket.GetSize());
251 } 252 }
252 253
253 void GetPersonalizedTicketSize(Kernel::HLERequestContext& ctx) { 254 void GetPersonalizedTicketSize(HLERequestContext& ctx) {
254 IPC::RequestParser rp{ctx}; 255 IPC::RequestParser rp{ctx};
255 const auto rights_id = rp.PopRaw<u128>(); 256 const auto rights_id = rp.PopRaw<u128>();
256 257
@@ -266,7 +267,7 @@ private:
266 rb.Push<u64>(ticket.GetSize()); 267 rb.Push<u64>(ticket.GetSize());
267 } 268 }
268 269
269 void GetCommonTicketData(Kernel::HLERequestContext& ctx) { 270 void GetCommonTicketData(HLERequestContext& ctx) {
270 IPC::RequestParser rp{ctx}; 271 IPC::RequestParser rp{ctx};
271 const auto rights_id = rp.PopRaw<u128>(); 272 const auto rights_id = rp.PopRaw<u128>();
272 273
@@ -285,7 +286,7 @@ private:
285 rb.Push<u64>(write_size); 286 rb.Push<u64>(write_size);
286 } 287 }
287 288
288 void GetPersonalizedTicketData(Kernel::HLERequestContext& ctx) { 289 void GetPersonalizedTicketData(HLERequestContext& ctx) {
289 IPC::RequestParser rp{ctx}; 290 IPC::RequestParser rp{ctx};
290 const auto rights_id = rp.PopRaw<u128>(); 291 const auto rights_id = rp.PopRaw<u128>();
291 292
@@ -307,8 +308,11 @@ private:
307 Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance(); 308 Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance();
308}; 309};
309 310
310void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 311void LoopProcess(Core::System& system) {
311 std::make_shared<ETicket>(system)->InstallAsService(service_manager); 312 auto server_manager = std::make_unique<ServerManager>(system);
313
314 server_manager->RegisterNamedService("es", std::make_shared<ETicket>(system));
315 ServerManager::RunServer(std::move(server_manager));
312} 316}
313 317
314} // namespace Service::ES 318} // namespace Service::ES
diff --git a/src/core/hle/service/es/es.h b/src/core/hle/service/es/es.h
index 530563550..317680625 100644
--- a/src/core/hle/service/es/es.h
+++ b/src/core/hle/service/es/es.h
@@ -7,13 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::ES { 10namespace Service::ES {
15 11
16/// Registers all ES services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::ES 14} // namespace Service::ES
diff --git a/src/core/hle/service/eupld/eupld.cpp b/src/core/hle/service/eupld/eupld.cpp
index d1553ace0..3cf27513a 100644
--- a/src/core/hle/service/eupld/eupld.cpp
+++ b/src/core/hle/service/eupld/eupld.cpp
@@ -4,8 +4,8 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/eupld/eupld.h" 6#include "core/hle/service/eupld/eupld.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::EUPLD { 10namespace Service::EUPLD {
11 11
@@ -44,9 +44,12 @@ public:
44 } 44 }
45}; 45};
46 46
47void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 47void LoopProcess(Core::System& system) {
48 std::make_shared<ErrorUploadContext>(system)->InstallAsService(sm); 48 auto server_manager = std::make_unique<ServerManager>(system);
49 std::make_shared<ErrorUploadRequest>(system)->InstallAsService(sm); 49
50 server_manager->RegisterNamedService("eupld:c", std::make_shared<ErrorUploadContext>(system));
51 server_manager->RegisterNamedService("eupld:r", std::make_shared<ErrorUploadRequest>(system));
52 ServerManager::RunServer(std::move(server_manager));
50} 53}
51 54
52} // namespace Service::EUPLD 55} // namespace Service::EUPLD
diff --git a/src/core/hle/service/eupld/eupld.h b/src/core/hle/service/eupld/eupld.h
index 5de8219be..8eb0a5b4f 100644
--- a/src/core/hle/service/eupld/eupld.h
+++ b/src/core/hle/service/eupld/eupld.h
@@ -7,13 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::EUPLD { 10namespace Service::EUPLD {
15 11
16/// Registers all EUPLD services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
18 13
19} // namespace Service::EUPLD 14} // namespace Service::EUPLD
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp
index 2e5919330..fe2ed8df8 100644
--- a/src/core/hle/service/fatal/fatal.cpp
+++ b/src/core/hle/service/fatal/fatal.cpp
@@ -9,10 +9,11 @@
9#include "common/scm_rev.h" 9#include "common/scm_rev.h"
10#include "common/swap.h" 10#include "common/swap.h"
11#include "core/core.h" 11#include "core/core.h"
12#include "core/hle/ipc_helpers.h"
13#include "core/hle/service/fatal/fatal.h" 12#include "core/hle/service/fatal/fatal.h"
14#include "core/hle/service/fatal/fatal_p.h" 13#include "core/hle/service/fatal/fatal_p.h"
15#include "core/hle/service/fatal/fatal_u.h" 14#include "core/hle/service/fatal/fatal_u.h"
15#include "core/hle/service/ipc_helpers.h"
16#include "core/hle/service/server_manager.h"
16#include "core/reporter.h" 17#include "core/reporter.h"
17 18
18namespace Service::Fatal { 19namespace Service::Fatal {
@@ -125,7 +126,7 @@ static void ThrowFatalError(Core::System& system, Result error_code, FatalType f
125 } 126 }
126} 127}
127 128
128void Module::Interface::ThrowFatal(Kernel::HLERequestContext& ctx) { 129void Module::Interface::ThrowFatal(HLERequestContext& ctx) {
129 LOG_ERROR(Service_Fatal, "called"); 130 LOG_ERROR(Service_Fatal, "called");
130 IPC::RequestParser rp{ctx}; 131 IPC::RequestParser rp{ctx};
131 const auto error_code = rp.Pop<Result>(); 132 const auto error_code = rp.Pop<Result>();
@@ -135,7 +136,7 @@ void Module::Interface::ThrowFatal(Kernel::HLERequestContext& ctx) {
135 rb.Push(ResultSuccess); 136 rb.Push(ResultSuccess);
136} 137}
137 138
138void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) { 139void Module::Interface::ThrowFatalWithPolicy(HLERequestContext& ctx) {
139 LOG_ERROR(Service_Fatal, "called"); 140 LOG_ERROR(Service_Fatal, "called");
140 IPC::RequestParser rp(ctx); 141 IPC::RequestParser rp(ctx);
141 const auto error_code = rp.Pop<Result>(); 142 const auto error_code = rp.Pop<Result>();
@@ -147,7 +148,7 @@ void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) {
147 rb.Push(ResultSuccess); 148 rb.Push(ResultSuccess);
148} 149}
149 150
150void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx) { 151void Module::Interface::ThrowFatalWithCpuContext(HLERequestContext& ctx) {
151 LOG_ERROR(Service_Fatal, "called"); 152 LOG_ERROR(Service_Fatal, "called");
152 IPC::RequestParser rp(ctx); 153 IPC::RequestParser rp(ctx);
153 const auto error_code = rp.Pop<Result>(); 154 const auto error_code = rp.Pop<Result>();
@@ -163,10 +164,13 @@ void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx)
163 rb.Push(ResultSuccess); 164 rb.Push(ResultSuccess);
164} 165}
165 166
166void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 167void LoopProcess(Core::System& system) {
168 auto server_manager = std::make_unique<ServerManager>(system);
167 auto module = std::make_shared<Module>(); 169 auto module = std::make_shared<Module>();
168 std::make_shared<Fatal_P>(module, system)->InstallAsService(service_manager); 170
169 std::make_shared<Fatal_U>(module, system)->InstallAsService(service_manager); 171 server_manager->RegisterNamedService("fatal:p", std::make_shared<Fatal_P>(module, system));
172 server_manager->RegisterNamedService("fatal:u", std::make_shared<Fatal_U>(module, system));
173 ServerManager::RunServer(std::move(server_manager));
170} 174}
171 175
172} // namespace Service::Fatal 176} // namespace Service::Fatal
diff --git a/src/core/hle/service/fatal/fatal.h b/src/core/hle/service/fatal/fatal.h
index a7a310f7b..f1c110406 100644
--- a/src/core/hle/service/fatal/fatal.h
+++ b/src/core/hle/service/fatal/fatal.h
@@ -19,15 +19,15 @@ public:
19 const char* name); 19 const char* name);
20 ~Interface() override; 20 ~Interface() override;
21 21
22 void ThrowFatal(Kernel::HLERequestContext& ctx); 22 void ThrowFatal(HLERequestContext& ctx);
23 void ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx); 23 void ThrowFatalWithPolicy(HLERequestContext& ctx);
24 void ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx); 24 void ThrowFatalWithCpuContext(HLERequestContext& ctx);
25 25
26 protected: 26 protected:
27 std::shared_ptr<Module> module; 27 std::shared_ptr<Module> module;
28 }; 28 };
29}; 29};
30 30
31void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); 31void LoopProcess(Core::System& system);
32 32
33} // namespace Service::Fatal 33} // namespace Service::Fatal
diff --git a/src/core/hle/service/fgm/fgm.cpp b/src/core/hle/service/fgm/fgm.cpp
index 7e9fb0385..6b3f77be2 100644
--- a/src/core/hle/service/fgm/fgm.cpp
+++ b/src/core/hle/service/fgm/fgm.cpp
@@ -3,8 +3,9 @@
3 3
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/ipc_helpers.h"
7#include "core/hle/service/fgm/fgm.h" 6#include "core/hle/service/fgm/fgm.h"
7#include "core/hle/service/ipc_helpers.h"
8#include "core/hle/service/server_manager.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h" 10#include "core/hle/service/sm/sm.h"
10 11
@@ -39,7 +40,7 @@ public:
39 } 40 }
40 41
41private: 42private:
42 void Initialize(Kernel::HLERequestContext& ctx) { 43 void Initialize(HLERequestContext& ctx) {
43 LOG_DEBUG(Service_FGM, "called"); 44 LOG_DEBUG(Service_FGM, "called");
44 45
45 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 46 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -63,11 +64,14 @@ public:
63 } 64 }
64}; 65};
65 66
66void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 67void LoopProcess(Core::System& system) {
67 std::make_shared<FGM>(system, "fgm")->InstallAsService(sm); 68 auto server_manager = std::make_unique<ServerManager>(system);
68 std::make_shared<FGM>(system, "fgm:0")->InstallAsService(sm); 69
69 std::make_shared<FGM>(system, "fgm:9")->InstallAsService(sm); 70 server_manager->RegisterNamedService("fgm", std::make_shared<FGM>(system, "fgm"));
70 std::make_shared<FGM_DBG>(system)->InstallAsService(sm); 71 server_manager->RegisterNamedService("fgm:0", std::make_shared<FGM>(system, "fgm:0"));
72 server_manager->RegisterNamedService("fgm:9", std::make_shared<FGM>(system, "fgm:9"));
73 server_manager->RegisterNamedService("fgm:dbg", std::make_shared<FGM_DBG>(system));
74 ServerManager::RunServer(std::move(server_manager));
71} 75}
72 76
73} // namespace Service::FGM 77} // namespace Service::FGM
diff --git a/src/core/hle/service/fgm/fgm.h b/src/core/hle/service/fgm/fgm.h
index 077e48812..9d2465c0f 100644
--- a/src/core/hle/service/fgm/fgm.h
+++ b/src/core/hle/service/fgm/fgm.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::FGM { 10namespace Service::FGM {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::FGM 14} // namespace Service::FGM
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index 177447bc1..dfcdd3ada 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -23,6 +23,7 @@
23#include "core/hle/service/filesystem/fsp_ldr.h" 23#include "core/hle/service/filesystem/fsp_ldr.h"
24#include "core/hle/service/filesystem/fsp_pr.h" 24#include "core/hle/service/filesystem/fsp_pr.h"
25#include "core/hle/service/filesystem/fsp_srv.h" 25#include "core/hle/service/filesystem/fsp_srv.h"
26#include "core/hle/service/server_manager.h"
26#include "core/loader/loader.h" 27#include "core/loader/loader.h"
27 28
28namespace Service::FileSystem { 29namespace Service::FileSystem {
@@ -796,10 +797,13 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove
796 } 797 }
797} 798}
798 799
799void InstallInterfaces(Core::System& system) { 800void LoopProcess(Core::System& system) {
800 std::make_shared<FSP_LDR>(system)->InstallAsService(system.ServiceManager()); 801 auto server_manager = std::make_unique<ServerManager>(system);
801 std::make_shared<FSP_PR>(system)->InstallAsService(system.ServiceManager()); 802
802 std::make_shared<FSP_SRV>(system)->InstallAsService(system.ServiceManager()); 803 server_manager->RegisterNamedService("fsp-ldr", std::make_shared<FSP_LDR>(system));
804 server_manager->RegisterNamedService("fsp:pr", std::make_shared<FSP_PR>(system));
805 server_manager->RegisterNamedService("fsp-srv", std::make_shared<FSP_SRV>(system));
806 ServerManager::RunServer(std::move(server_manager));
803} 807}
804 808
805} // namespace Service::FileSystem 809} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
index 5b27de9fa..a5c1c9d3e 100644
--- a/src/core/hle/service/filesystem/filesystem.h
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -139,7 +139,7 @@ private:
139 Core::System& system; 139 Core::System& system;
140}; 140};
141 141
142void InstallInterfaces(Core::System& system); 142void LoopProcess(Core::System& system);
143 143
144// A class that wraps a VfsDirectory with methods that return ResultVal and Result instead of 144// A class that wraps a VfsDirectory with methods that return ResultVal and Result instead of
145// pointers and booleans. This makes using a VfsDirectory with switch services much easier and 145// pointers and booleans. This makes using a VfsDirectory with switch services much easier and
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index e76346ca9..9e559d97e 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -24,9 +24,9 @@
24#include "core/file_sys/savedata_factory.h" 24#include "core/file_sys/savedata_factory.h"
25#include "core/file_sys/system_archive/system_archive.h" 25#include "core/file_sys/system_archive/system_archive.h"
26#include "core/file_sys/vfs.h" 26#include "core/file_sys/vfs.h"
27#include "core/hle/ipc_helpers.h"
28#include "core/hle/service/filesystem/filesystem.h" 27#include "core/hle/service/filesystem/filesystem.h"
29#include "core/hle/service/filesystem/fsp_srv.h" 28#include "core/hle/service/filesystem/fsp_srv.h"
29#include "core/hle/service/ipc_helpers.h"
30#include "core/reporter.h" 30#include "core/reporter.h"
31 31
32namespace Service::FileSystem { 32namespace Service::FileSystem {
@@ -57,8 +57,7 @@ enum class FileSystemType : u8 {
57class IStorage final : public ServiceFramework<IStorage> { 57class IStorage final : public ServiceFramework<IStorage> {
58public: 58public:
59 explicit IStorage(Core::System& system_, FileSys::VirtualFile backend_) 59 explicit IStorage(Core::System& system_, FileSys::VirtualFile backend_)
60 : ServiceFramework{system_, "IStorage", ServiceThreadType::CreateNew}, 60 : ServiceFramework{system_, "IStorage"}, backend(std::move(backend_)) {
61 backend(std::move(backend_)) {
62 static const FunctionInfo functions[] = { 61 static const FunctionInfo functions[] = {
63 {0, &IStorage::Read, "Read"}, 62 {0, &IStorage::Read, "Read"},
64 {1, nullptr, "Write"}, 63 {1, nullptr, "Write"},
@@ -73,7 +72,7 @@ public:
73private: 72private:
74 FileSys::VirtualFile backend; 73 FileSys::VirtualFile backend;
75 74
76 void Read(Kernel::HLERequestContext& ctx) { 75 void Read(HLERequestContext& ctx) {
77 IPC::RequestParser rp{ctx}; 76 IPC::RequestParser rp{ctx};
78 const s64 offset = rp.Pop<s64>(); 77 const s64 offset = rp.Pop<s64>();
79 const s64 length = rp.Pop<s64>(); 78 const s64 length = rp.Pop<s64>();
@@ -103,7 +102,7 @@ private:
103 rb.Push(ResultSuccess); 102 rb.Push(ResultSuccess);
104 } 103 }
105 104
106 void GetSize(Kernel::HLERequestContext& ctx) { 105 void GetSize(HLERequestContext& ctx) {
107 const u64 size = backend->GetSize(); 106 const u64 size = backend->GetSize();
108 LOG_DEBUG(Service_FS, "called, size={}", size); 107 LOG_DEBUG(Service_FS, "called, size={}", size);
109 108
@@ -116,8 +115,7 @@ private:
116class IFile final : public ServiceFramework<IFile> { 115class IFile final : public ServiceFramework<IFile> {
117public: 116public:
118 explicit IFile(Core::System& system_, FileSys::VirtualFile backend_) 117 explicit IFile(Core::System& system_, FileSys::VirtualFile backend_)
119 : ServiceFramework{system_, "IFile", ServiceThreadType::CreateNew}, 118 : ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) {
120 backend(std::move(backend_)) {
121 static const FunctionInfo functions[] = { 119 static const FunctionInfo functions[] = {
122 {0, &IFile::Read, "Read"}, 120 {0, &IFile::Read, "Read"},
123 {1, &IFile::Write, "Write"}, 121 {1, &IFile::Write, "Write"},
@@ -133,7 +131,7 @@ public:
133private: 131private:
134 FileSys::VirtualFile backend; 132 FileSys::VirtualFile backend;
135 133
136 void Read(Kernel::HLERequestContext& ctx) { 134 void Read(HLERequestContext& ctx) {
137 IPC::RequestParser rp{ctx}; 135 IPC::RequestParser rp{ctx};
138 const u64 option = rp.Pop<u64>(); 136 const u64 option = rp.Pop<u64>();
139 const s64 offset = rp.Pop<s64>(); 137 const s64 offset = rp.Pop<s64>();
@@ -167,7 +165,7 @@ private:
167 rb.Push(static_cast<u64>(output.size())); 165 rb.Push(static_cast<u64>(output.size()));
168 } 166 }
169 167
170 void Write(Kernel::HLERequestContext& ctx) { 168 void Write(HLERequestContext& ctx) {
171 IPC::RequestParser rp{ctx}; 169 IPC::RequestParser rp{ctx};
172 const u64 option = rp.Pop<u64>(); 170 const u64 option = rp.Pop<u64>();
173 const s64 offset = rp.Pop<s64>(); 171 const s64 offset = rp.Pop<s64>();
@@ -210,7 +208,7 @@ private:
210 rb.Push(ResultSuccess); 208 rb.Push(ResultSuccess);
211 } 209 }
212 210
213 void Flush(Kernel::HLERequestContext& ctx) { 211 void Flush(HLERequestContext& ctx) {
214 LOG_DEBUG(Service_FS, "called"); 212 LOG_DEBUG(Service_FS, "called");
215 213
216 // Exists for SDK compatibiltity -- No need to flush file. 214 // Exists for SDK compatibiltity -- No need to flush file.
@@ -219,7 +217,7 @@ private:
219 rb.Push(ResultSuccess); 217 rb.Push(ResultSuccess);
220 } 218 }
221 219
222 void SetSize(Kernel::HLERequestContext& ctx) { 220 void SetSize(HLERequestContext& ctx) {
223 IPC::RequestParser rp{ctx}; 221 IPC::RequestParser rp{ctx};
224 const u64 size = rp.Pop<u64>(); 222 const u64 size = rp.Pop<u64>();
225 LOG_DEBUG(Service_FS, "called, size={}", size); 223 LOG_DEBUG(Service_FS, "called, size={}", size);
@@ -230,7 +228,7 @@ private:
230 rb.Push(ResultSuccess); 228 rb.Push(ResultSuccess);
231 } 229 }
232 230
233 void GetSize(Kernel::HLERequestContext& ctx) { 231 void GetSize(HLERequestContext& ctx) {
234 const u64 size = backend->GetSize(); 232 const u64 size = backend->GetSize();
235 LOG_DEBUG(Service_FS, "called, size={}", size); 233 LOG_DEBUG(Service_FS, "called, size={}", size);
236 234
@@ -254,8 +252,7 @@ static void BuildEntryIndex(std::vector<FileSys::Entry>& entries, const std::vec
254class IDirectory final : public ServiceFramework<IDirectory> { 252class IDirectory final : public ServiceFramework<IDirectory> {
255public: 253public:
256 explicit IDirectory(Core::System& system_, FileSys::VirtualDir backend_) 254 explicit IDirectory(Core::System& system_, FileSys::VirtualDir backend_)
257 : ServiceFramework{system_, "IDirectory", ServiceThreadType::CreateNew}, 255 : ServiceFramework{system_, "IDirectory"}, backend(std::move(backend_)) {
258 backend(std::move(backend_)) {
259 static const FunctionInfo functions[] = { 256 static const FunctionInfo functions[] = {
260 {0, &IDirectory::Read, "Read"}, 257 {0, &IDirectory::Read, "Read"},
261 {1, &IDirectory::GetEntryCount, "GetEntryCount"}, 258 {1, &IDirectory::GetEntryCount, "GetEntryCount"},
@@ -273,7 +270,7 @@ private:
273 std::vector<FileSys::Entry> entries; 270 std::vector<FileSys::Entry> entries;
274 u64 next_entry_index = 0; 271 u64 next_entry_index = 0;
275 272
276 void Read(Kernel::HLERequestContext& ctx) { 273 void Read(HLERequestContext& ctx) {
277 LOG_DEBUG(Service_FS, "called."); 274 LOG_DEBUG(Service_FS, "called.");
278 275
279 // Calculate how many entries we can fit in the output buffer 276 // Calculate how many entries we can fit in the output buffer
@@ -297,7 +294,7 @@ private:
297 rb.Push(actual_entries); 294 rb.Push(actual_entries);
298 } 295 }
299 296
300 void GetEntryCount(Kernel::HLERequestContext& ctx) { 297 void GetEntryCount(HLERequestContext& ctx) {
301 LOG_DEBUG(Service_FS, "called"); 298 LOG_DEBUG(Service_FS, "called");
302 299
303 u64 count = entries.size() - next_entry_index; 300 u64 count = entries.size() - next_entry_index;
@@ -311,8 +308,8 @@ private:
311class IFileSystem final : public ServiceFramework<IFileSystem> { 308class IFileSystem final : public ServiceFramework<IFileSystem> {
312public: 309public:
313 explicit IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_) 310 explicit IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_)
314 : ServiceFramework{system_, "IFileSystem", ServiceThreadType::CreateNew}, 311 : ServiceFramework{system_, "IFileSystem"}, backend{std::move(backend_)}, size{std::move(
315 backend{std::move(backend_)}, size{std::move(size_)} { 312 size_)} {
316 static const FunctionInfo functions[] = { 313 static const FunctionInfo functions[] = {
317 {0, &IFileSystem::CreateFile, "CreateFile"}, 314 {0, &IFileSystem::CreateFile, "CreateFile"},
318 {1, &IFileSystem::DeleteFile, "DeleteFile"}, 315 {1, &IFileSystem::DeleteFile, "DeleteFile"},
@@ -334,7 +331,7 @@ public:
334 RegisterHandlers(functions); 331 RegisterHandlers(functions);
335 } 332 }
336 333
337 void CreateFile(Kernel::HLERequestContext& ctx) { 334 void CreateFile(HLERequestContext& ctx) {
338 IPC::RequestParser rp{ctx}; 335 IPC::RequestParser rp{ctx};
339 336
340 const auto file_buffer = ctx.ReadBuffer(); 337 const auto file_buffer = ctx.ReadBuffer();
@@ -350,7 +347,7 @@ public:
350 rb.Push(backend.CreateFile(name, file_size)); 347 rb.Push(backend.CreateFile(name, file_size));
351 } 348 }
352 349
353 void DeleteFile(Kernel::HLERequestContext& ctx) { 350 void DeleteFile(HLERequestContext& ctx) {
354 const auto file_buffer = ctx.ReadBuffer(); 351 const auto file_buffer = ctx.ReadBuffer();
355 const std::string name = Common::StringFromBuffer(file_buffer); 352 const std::string name = Common::StringFromBuffer(file_buffer);
356 353
@@ -360,7 +357,7 @@ public:
360 rb.Push(backend.DeleteFile(name)); 357 rb.Push(backend.DeleteFile(name));
361 } 358 }
362 359
363 void CreateDirectory(Kernel::HLERequestContext& ctx) { 360 void CreateDirectory(HLERequestContext& ctx) {
364 const auto file_buffer = ctx.ReadBuffer(); 361 const auto file_buffer = ctx.ReadBuffer();
365 const std::string name = Common::StringFromBuffer(file_buffer); 362 const std::string name = Common::StringFromBuffer(file_buffer);
366 363
@@ -370,7 +367,7 @@ public:
370 rb.Push(backend.CreateDirectory(name)); 367 rb.Push(backend.CreateDirectory(name));
371 } 368 }
372 369
373 void DeleteDirectory(Kernel::HLERequestContext& ctx) { 370 void DeleteDirectory(HLERequestContext& ctx) {
374 const auto file_buffer = ctx.ReadBuffer(); 371 const auto file_buffer = ctx.ReadBuffer();
375 const std::string name = Common::StringFromBuffer(file_buffer); 372 const std::string name = Common::StringFromBuffer(file_buffer);
376 373
@@ -380,7 +377,7 @@ public:
380 rb.Push(backend.DeleteDirectory(name)); 377 rb.Push(backend.DeleteDirectory(name));
381 } 378 }
382 379
383 void DeleteDirectoryRecursively(Kernel::HLERequestContext& ctx) { 380 void DeleteDirectoryRecursively(HLERequestContext& ctx) {
384 const auto file_buffer = ctx.ReadBuffer(); 381 const auto file_buffer = ctx.ReadBuffer();
385 const std::string name = Common::StringFromBuffer(file_buffer); 382 const std::string name = Common::StringFromBuffer(file_buffer);
386 383
@@ -390,7 +387,7 @@ public:
390 rb.Push(backend.DeleteDirectoryRecursively(name)); 387 rb.Push(backend.DeleteDirectoryRecursively(name));
391 } 388 }
392 389
393 void CleanDirectoryRecursively(Kernel::HLERequestContext& ctx) { 390 void CleanDirectoryRecursively(HLERequestContext& ctx) {
394 const auto file_buffer = ctx.ReadBuffer(); 391 const auto file_buffer = ctx.ReadBuffer();
395 const std::string name = Common::StringFromBuffer(file_buffer); 392 const std::string name = Common::StringFromBuffer(file_buffer);
396 393
@@ -400,7 +397,7 @@ public:
400 rb.Push(backend.CleanDirectoryRecursively(name)); 397 rb.Push(backend.CleanDirectoryRecursively(name));
401 } 398 }
402 399
403 void RenameFile(Kernel::HLERequestContext& ctx) { 400 void RenameFile(HLERequestContext& ctx) {
404 const std::string src_name = Common::StringFromBuffer(ctx.ReadBuffer(0)); 401 const std::string src_name = Common::StringFromBuffer(ctx.ReadBuffer(0));
405 const std::string dst_name = Common::StringFromBuffer(ctx.ReadBuffer(1)); 402 const std::string dst_name = Common::StringFromBuffer(ctx.ReadBuffer(1));
406 403
@@ -410,7 +407,7 @@ public:
410 rb.Push(backend.RenameFile(src_name, dst_name)); 407 rb.Push(backend.RenameFile(src_name, dst_name));
411 } 408 }
412 409
413 void OpenFile(Kernel::HLERequestContext& ctx) { 410 void OpenFile(HLERequestContext& ctx) {
414 IPC::RequestParser rp{ctx}; 411 IPC::RequestParser rp{ctx};
415 412
416 const auto file_buffer = ctx.ReadBuffer(); 413 const auto file_buffer = ctx.ReadBuffer();
@@ -434,7 +431,7 @@ public:
434 rb.PushIpcInterface<IFile>(std::move(file)); 431 rb.PushIpcInterface<IFile>(std::move(file));
435 } 432 }
436 433
437 void OpenDirectory(Kernel::HLERequestContext& ctx) { 434 void OpenDirectory(HLERequestContext& ctx) {
438 IPC::RequestParser rp{ctx}; 435 IPC::RequestParser rp{ctx};
439 436
440 const auto file_buffer = ctx.ReadBuffer(); 437 const auto file_buffer = ctx.ReadBuffer();
@@ -459,7 +456,7 @@ public:
459 rb.PushIpcInterface<IDirectory>(std::move(directory)); 456 rb.PushIpcInterface<IDirectory>(std::move(directory));
460 } 457 }
461 458
462 void GetEntryType(Kernel::HLERequestContext& ctx) { 459 void GetEntryType(HLERequestContext& ctx) {
463 const auto file_buffer = ctx.ReadBuffer(); 460 const auto file_buffer = ctx.ReadBuffer();
464 const std::string name = Common::StringFromBuffer(file_buffer); 461 const std::string name = Common::StringFromBuffer(file_buffer);
465 462
@@ -477,14 +474,14 @@ public:
477 rb.Push<u32>(static_cast<u32>(*result)); 474 rb.Push<u32>(static_cast<u32>(*result));
478 } 475 }
479 476
480 void Commit(Kernel::HLERequestContext& ctx) { 477 void Commit(HLERequestContext& ctx) {
481 LOG_WARNING(Service_FS, "(STUBBED) called"); 478 LOG_WARNING(Service_FS, "(STUBBED) called");
482 479
483 IPC::ResponseBuilder rb{ctx, 2}; 480 IPC::ResponseBuilder rb{ctx, 2};
484 rb.Push(ResultSuccess); 481 rb.Push(ResultSuccess);
485 } 482 }
486 483
487 void GetFreeSpaceSize(Kernel::HLERequestContext& ctx) { 484 void GetFreeSpaceSize(HLERequestContext& ctx) {
488 LOG_DEBUG(Service_FS, "called"); 485 LOG_DEBUG(Service_FS, "called");
489 486
490 IPC::ResponseBuilder rb{ctx, 4}; 487 IPC::ResponseBuilder rb{ctx, 4};
@@ -492,7 +489,7 @@ public:
492 rb.Push(size.get_free_size()); 489 rb.Push(size.get_free_size());
493 } 490 }
494 491
495 void GetTotalSpaceSize(Kernel::HLERequestContext& ctx) { 492 void GetTotalSpaceSize(HLERequestContext& ctx) {
496 LOG_DEBUG(Service_FS, "called"); 493 LOG_DEBUG(Service_FS, "called");
497 494
498 IPC::ResponseBuilder rb{ctx, 4}; 495 IPC::ResponseBuilder rb{ctx, 4};
@@ -500,7 +497,7 @@ public:
500 rb.Push(size.get_total_size()); 497 rb.Push(size.get_total_size());
501 } 498 }
502 499
503 void GetFileTimeStampRaw(Kernel::HLERequestContext& ctx) { 500 void GetFileTimeStampRaw(HLERequestContext& ctx) {
504 const auto file_buffer = ctx.ReadBuffer(); 501 const auto file_buffer = ctx.ReadBuffer();
505 const std::string name = Common::StringFromBuffer(file_buffer); 502 const std::string name = Common::StringFromBuffer(file_buffer);
506 503
@@ -536,7 +533,7 @@ public:
536 FindAllSaves(space); 533 FindAllSaves(space);
537 } 534 }
538 535
539 void ReadSaveDataInfo(Kernel::HLERequestContext& ctx) { 536 void ReadSaveDataInfo(HLERequestContext& ctx) {
540 LOG_DEBUG(Service_FS, "called"); 537 LOG_DEBUG(Service_FS, "called");
541 538
542 // Calculate how many entries we can fit in the output buffer 539 // Calculate how many entries we can fit in the output buffer
@@ -814,7 +811,7 @@ FSP_SRV::FSP_SRV(Core::System& system_)
814 811
815FSP_SRV::~FSP_SRV() = default; 812FSP_SRV::~FSP_SRV() = default;
816 813
817void FSP_SRV::SetCurrentProcess(Kernel::HLERequestContext& ctx) { 814void FSP_SRV::SetCurrentProcess(HLERequestContext& ctx) {
818 IPC::RequestParser rp{ctx}; 815 IPC::RequestParser rp{ctx};
819 current_process_id = rp.Pop<u64>(); 816 current_process_id = rp.Pop<u64>();
820 817
@@ -824,7 +821,7 @@ void FSP_SRV::SetCurrentProcess(Kernel::HLERequestContext& ctx) {
824 rb.Push(ResultSuccess); 821 rb.Push(ResultSuccess);
825} 822}
826 823
827void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) { 824void FSP_SRV::OpenFileSystemWithPatch(HLERequestContext& ctx) {
828 IPC::RequestParser rp{ctx}; 825 IPC::RequestParser rp{ctx};
829 826
830 const auto type = rp.PopRaw<FileSystemType>(); 827 const auto type = rp.PopRaw<FileSystemType>();
@@ -835,7 +832,7 @@ void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) {
835 rb.Push(ResultUnknown); 832 rb.Push(ResultUnknown);
836} 833}
837 834
838void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) { 835void FSP_SRV::OpenSdCardFileSystem(HLERequestContext& ctx) {
839 LOG_DEBUG(Service_FS, "called"); 836 LOG_DEBUG(Service_FS, "called");
840 837
841 auto filesystem = 838 auto filesystem =
@@ -847,7 +844,7 @@ void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) {
847 rb.PushIpcInterface<IFileSystem>(std::move(filesystem)); 844 rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
848} 845}
849 846
850void FSP_SRV::CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx) { 847void FSP_SRV::CreateSaveDataFileSystem(HLERequestContext& ctx) {
851 IPC::RequestParser rp{ctx}; 848 IPC::RequestParser rp{ctx};
852 849
853 auto save_struct = rp.PopRaw<FileSys::SaveDataAttribute>(); 850 auto save_struct = rp.PopRaw<FileSys::SaveDataAttribute>();
@@ -863,7 +860,7 @@ void FSP_SRV::CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
863 rb.Push(ResultSuccess); 860 rb.Push(ResultSuccess);
864} 861}
865 862
866void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) { 863void FSP_SRV::OpenSaveDataFileSystem(HLERequestContext& ctx) {
867 IPC::RequestParser rp{ctx}; 864 IPC::RequestParser rp{ctx};
868 865
869 struct Parameters { 866 struct Parameters {
@@ -908,12 +905,12 @@ void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
908 rb.PushIpcInterface<IFileSystem>(std::move(filesystem)); 905 rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
909} 906}
910 907
911void FSP_SRV::OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx) { 908void FSP_SRV::OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx) {
912 LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem"); 909 LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem");
913 OpenSaveDataFileSystem(ctx); 910 OpenSaveDataFileSystem(ctx);
914} 911}
915 912
916void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx) { 913void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx) {
917 IPC::RequestParser rp{ctx}; 914 IPC::RequestParser rp{ctx};
918 const auto space = rp.PopRaw<FileSys::SaveDataSpaceId>(); 915 const auto space = rp.PopRaw<FileSys::SaveDataSpaceId>();
919 LOG_INFO(Service_FS, "called, space={}", space); 916 LOG_INFO(Service_FS, "called, space={}", space);
@@ -924,15 +921,14 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext&
924 std::make_shared<ISaveDataInfoReader>(system, space, fsc)); 921 std::make_shared<ISaveDataInfoReader>(system, space, fsc));
925} 922}
926 923
927void FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute(Kernel::HLERequestContext& ctx) { 924void FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx) {
928 LOG_WARNING(Service_FS, "(STUBBED) called."); 925 LOG_WARNING(Service_FS, "(STUBBED) called.");
929 926
930 IPC::ResponseBuilder rb{ctx, 2}; 927 IPC::ResponseBuilder rb{ctx, 2};
931 rb.Push(ResultSuccess); 928 rb.Push(ResultSuccess);
932} 929}
933 930
934void FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( 931void FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(HLERequestContext& ctx) {
935 Kernel::HLERequestContext& ctx) {
936 IPC::RequestParser rp{ctx}; 932 IPC::RequestParser rp{ctx};
937 933
938 struct Parameters { 934 struct Parameters {
@@ -958,7 +954,7 @@ void FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(
958 rb.Push(flags); 954 rb.Push(flags);
959} 955}
960 956
961void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { 957void FSP_SRV::OpenDataStorageByCurrentProcess(HLERequestContext& ctx) {
962 LOG_DEBUG(Service_FS, "called"); 958 LOG_DEBUG(Service_FS, "called");
963 959
964 auto current_romfs = fsc.OpenRomFSCurrentProcess(); 960 auto current_romfs = fsc.OpenRomFSCurrentProcess();
@@ -977,7 +973,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
977 rb.PushIpcInterface<IStorage>(std::move(storage)); 973 rb.PushIpcInterface<IStorage>(std::move(storage));
978} 974}
979 975
980void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) { 976void FSP_SRV::OpenDataStorageByDataId(HLERequestContext& ctx) {
981 IPC::RequestParser rp{ctx}; 977 IPC::RequestParser rp{ctx};
982 const auto storage_id = rp.PopRaw<FileSys::StorageId>(); 978 const auto storage_id = rp.PopRaw<FileSys::StorageId>();
983 const auto unknown = rp.PopRaw<u32>(); 979 const auto unknown = rp.PopRaw<u32>();
@@ -1017,7 +1013,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) {
1017 rb.PushIpcInterface<IStorage>(std::move(storage)); 1013 rb.PushIpcInterface<IStorage>(std::move(storage));
1018} 1014}
1019 1015
1020void FSP_SRV::OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { 1016void FSP_SRV::OpenPatchDataStorageByCurrentProcess(HLERequestContext& ctx) {
1021 IPC::RequestParser rp{ctx}; 1017 IPC::RequestParser rp{ctx};
1022 1018
1023 const auto storage_id = rp.PopRaw<FileSys::StorageId>(); 1019 const auto storage_id = rp.PopRaw<FileSys::StorageId>();
@@ -1029,7 +1025,7 @@ void FSP_SRV::OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ct
1029 rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND); 1025 rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND);
1030} 1026}
1031 1027
1032void FSP_SRV::OpenDataStorageWithProgramIndex(Kernel::HLERequestContext& ctx) { 1028void FSP_SRV::OpenDataStorageWithProgramIndex(HLERequestContext& ctx) {
1033 IPC::RequestParser rp{ctx}; 1029 IPC::RequestParser rp{ctx};
1034 1030
1035 const auto program_index = rp.PopRaw<u8>(); 1031 const auto program_index = rp.PopRaw<u8>();
@@ -1056,7 +1052,7 @@ void FSP_SRV::OpenDataStorageWithProgramIndex(Kernel::HLERequestContext& ctx) {
1056 rb.PushIpcInterface<IStorage>(std::move(storage)); 1052 rb.PushIpcInterface<IStorage>(std::move(storage));
1057} 1053}
1058 1054
1059void FSP_SRV::DisableAutoSaveDataCreation(Kernel::HLERequestContext& ctx) { 1055void FSP_SRV::DisableAutoSaveDataCreation(HLERequestContext& ctx) {
1060 LOG_DEBUG(Service_FS, "called"); 1056 LOG_DEBUG(Service_FS, "called");
1061 1057
1062 fsc.SetAutoSaveDataCreation(false); 1058 fsc.SetAutoSaveDataCreation(false);
@@ -1065,7 +1061,7 @@ void FSP_SRV::DisableAutoSaveDataCreation(Kernel::HLERequestContext& ctx) {
1065 rb.Push(ResultSuccess); 1061 rb.Push(ResultSuccess);
1066} 1062}
1067 1063
1068void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { 1064void FSP_SRV::SetGlobalAccessLogMode(HLERequestContext& ctx) {
1069 IPC::RequestParser rp{ctx}; 1065 IPC::RequestParser rp{ctx};
1070 access_log_mode = rp.PopEnum<AccessLogMode>(); 1066 access_log_mode = rp.PopEnum<AccessLogMode>();
1071 1067
@@ -1075,7 +1071,7 @@ void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
1075 rb.Push(ResultSuccess); 1071 rb.Push(ResultSuccess);
1076} 1072}
1077 1073
1078void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { 1074void FSP_SRV::GetGlobalAccessLogMode(HLERequestContext& ctx) {
1079 LOG_DEBUG(Service_FS, "called"); 1075 LOG_DEBUG(Service_FS, "called");
1080 1076
1081 IPC::ResponseBuilder rb{ctx, 3}; 1077 IPC::ResponseBuilder rb{ctx, 3};
@@ -1083,7 +1079,7 @@ void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
1083 rb.PushEnum(access_log_mode); 1079 rb.PushEnum(access_log_mode);
1084} 1080}
1085 1081
1086void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) { 1082void FSP_SRV::OutputAccessLogToSdCard(HLERequestContext& ctx) {
1087 const auto raw = ctx.ReadBufferCopy(); 1083 const auto raw = ctx.ReadBufferCopy();
1088 auto log = Common::StringFromFixedZeroTerminatedBuffer( 1084 auto log = Common::StringFromFixedZeroTerminatedBuffer(
1089 reinterpret_cast<const char*>(raw.data()), raw.size()); 1085 reinterpret_cast<const char*>(raw.data()), raw.size());
@@ -1096,7 +1092,7 @@ void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) {
1096 rb.Push(ResultSuccess); 1092 rb.Push(ResultSuccess);
1097} 1093}
1098 1094
1099void FSP_SRV::GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx) { 1095void FSP_SRV::GetProgramIndexForAccessLog(HLERequestContext& ctx) {
1100 LOG_DEBUG(Service_FS, "called"); 1096 LOG_DEBUG(Service_FS, "called");
1101 1097
1102 IPC::ResponseBuilder rb{ctx, 4}; 1098 IPC::ResponseBuilder rb{ctx, 4};
@@ -1105,7 +1101,7 @@ void FSP_SRV::GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx) {
1105 rb.Push(access_log_program_index); 1101 rb.Push(access_log_program_index);
1106} 1102}
1107 1103
1108void FSP_SRV::GetCacheStorageSize(Kernel::HLERequestContext& ctx) { 1104void FSP_SRV::GetCacheStorageSize(HLERequestContext& ctx) {
1109 IPC::RequestParser rp{ctx}; 1105 IPC::RequestParser rp{ctx};
1110 const auto index{rp.Pop<s32>()}; 1106 const auto index{rp.Pop<s32>()};
1111 1107
@@ -1131,14 +1127,14 @@ public:
1131private: 1127private:
1132 FileSys::VirtualFile backend; 1128 FileSys::VirtualFile backend;
1133 1129
1134 void Add(Kernel::HLERequestContext& ctx) { 1130 void Add(HLERequestContext& ctx) {
1135 LOG_WARNING(Service_FS, "(STUBBED) called"); 1131 LOG_WARNING(Service_FS, "(STUBBED) called");
1136 1132
1137 IPC::ResponseBuilder rb{ctx, 2}; 1133 IPC::ResponseBuilder rb{ctx, 2};
1138 rb.Push(ResultSuccess); 1134 rb.Push(ResultSuccess);
1139 } 1135 }
1140 1136
1141 void Commit(Kernel::HLERequestContext& ctx) { 1137 void Commit(HLERequestContext& ctx) {
1142 LOG_WARNING(Service_FS, "(STUBBED) called"); 1138 LOG_WARNING(Service_FS, "(STUBBED) called");
1143 1139
1144 IPC::ResponseBuilder rb{ctx, 2}; 1140 IPC::ResponseBuilder rb{ctx, 2};
@@ -1146,7 +1142,7 @@ private:
1146 } 1142 }
1147}; 1143};
1148 1144
1149void FSP_SRV::OpenMultiCommitManager(Kernel::HLERequestContext& ctx) { 1145void FSP_SRV::OpenMultiCommitManager(HLERequestContext& ctx) {
1150 LOG_DEBUG(Service_FS, "called"); 1146 LOG_DEBUG(Service_FS, "called");
1151 1147
1152 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1148 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h
index 3d88b97f9..49f17c7c3 100644
--- a/src/core/hle/service/filesystem/fsp_srv.h
+++ b/src/core/hle/service/filesystem/fsp_srv.h
@@ -35,26 +35,26 @@ public:
35 ~FSP_SRV() override; 35 ~FSP_SRV() override;
36 36
37private: 37private:
38 void SetCurrentProcess(Kernel::HLERequestContext& ctx); 38 void SetCurrentProcess(HLERequestContext& ctx);
39 void OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx); 39 void OpenFileSystemWithPatch(HLERequestContext& ctx);
40 void OpenSdCardFileSystem(Kernel::HLERequestContext& ctx); 40 void OpenSdCardFileSystem(HLERequestContext& ctx);
41 void CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx); 41 void CreateSaveDataFileSystem(HLERequestContext& ctx);
42 void OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx); 42 void OpenSaveDataFileSystem(HLERequestContext& ctx);
43 void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx); 43 void OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx);
44 void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx); 44 void OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx);
45 void WriteSaveDataFileSystemExtraDataBySaveDataAttribute(Kernel::HLERequestContext& ctx); 45 void WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx);
46 void ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(Kernel::HLERequestContext& ctx); 46 void ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(HLERequestContext& ctx);
47 void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); 47 void OpenDataStorageByCurrentProcess(HLERequestContext& ctx);
48 void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx); 48 void OpenDataStorageByDataId(HLERequestContext& ctx);
49 void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); 49 void OpenPatchDataStorageByCurrentProcess(HLERequestContext& ctx);
50 void OpenDataStorageWithProgramIndex(Kernel::HLERequestContext& ctx); 50 void OpenDataStorageWithProgramIndex(HLERequestContext& ctx);
51 void DisableAutoSaveDataCreation(Kernel::HLERequestContext& ctx); 51 void DisableAutoSaveDataCreation(HLERequestContext& ctx);
52 void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); 52 void SetGlobalAccessLogMode(HLERequestContext& ctx);
53 void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); 53 void GetGlobalAccessLogMode(HLERequestContext& ctx);
54 void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx); 54 void OutputAccessLogToSdCard(HLERequestContext& ctx);
55 void GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx); 55 void GetProgramIndexForAccessLog(HLERequestContext& ctx);
56 void OpenMultiCommitManager(Kernel::HLERequestContext& ctx); 56 void OpenMultiCommitManager(HLERequestContext& ctx);
57 void GetCacheStorageSize(Kernel::HLERequestContext& ctx); 57 void GetCacheStorageSize(HLERequestContext& ctx);
58 58
59 FileSystemController& fsc; 59 FileSystemController& fsc;
60 const FileSys::ContentProvider& content_provider; 60 const FileSys::ContentProvider& content_provider;
diff --git a/src/core/hle/service/friend/errors.h b/src/core/hle/service/friend/errors.h
deleted file mode 100644
index ff525d865..000000000
--- a/src/core/hle/service/friend/errors.h
+++ /dev/null
@@ -1,11 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/result.h"
7
8namespace Service::Friend {
9
10constexpr Result ERR_NO_NOTIFICATIONS{ErrorModule::Account, 15};
11}
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index fad532115..9d05f9801 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -5,12 +5,13 @@
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "common/uuid.h" 6#include "common/uuid.h"
7#include "core/core.h" 7#include "core/core.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/k_event.h" 8#include "core/hle/kernel/k_event.h"
10#include "core/hle/service/friend/errors.h" 9#include "core/hle/service/acc/errors.h"
11#include "core/hle/service/friend/friend.h" 10#include "core/hle/service/friend/friend.h"
12#include "core/hle/service/friend/friend_interface.h" 11#include "core/hle/service/friend/friend_interface.h"
12#include "core/hle/service/ipc_helpers.h"
13#include "core/hle/service/kernel_helpers.h" 13#include "core/hle/service/kernel_helpers.h"
14#include "core/hle/service/server_manager.h"
14 15
15namespace Service::Friend { 16namespace Service::Friend {
16 17
@@ -135,7 +136,7 @@ private:
135 }; 136 };
136 static_assert(sizeof(SizedFriendFilter) == 0x10, "SizedFriendFilter is an invalid size"); 137 static_assert(sizeof(SizedFriendFilter) == 0x10, "SizedFriendFilter is an invalid size");
137 138
138 void GetCompletionEvent(Kernel::HLERequestContext& ctx) { 139 void GetCompletionEvent(HLERequestContext& ctx) {
139 LOG_DEBUG(Service_Friend, "called"); 140 LOG_DEBUG(Service_Friend, "called");
140 141
141 IPC::ResponseBuilder rb{ctx, 2, 1}; 142 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -143,7 +144,7 @@ private:
143 rb.PushCopyObjects(completion_event->GetReadableEvent()); 144 rb.PushCopyObjects(completion_event->GetReadableEvent());
144 } 145 }
145 146
146 void GetBlockedUserListIds(Kernel::HLERequestContext& ctx) { 147 void GetBlockedUserListIds(HLERequestContext& ctx) {
147 // This is safe to stub, as there should be no adverse consequences from reporting no 148 // This is safe to stub, as there should be no adverse consequences from reporting no
148 // blocked users. 149 // blocked users.
149 LOG_WARNING(Service_Friend, "(STUBBED) called"); 150 LOG_WARNING(Service_Friend, "(STUBBED) called");
@@ -152,21 +153,21 @@ private:
152 rb.Push<u32>(0); // Indicates there are no blocked users 153 rb.Push<u32>(0); // Indicates there are no blocked users
153 } 154 }
154 155
155 void DeclareCloseOnlinePlaySession(Kernel::HLERequestContext& ctx) { 156 void DeclareCloseOnlinePlaySession(HLERequestContext& ctx) {
156 // Stub used by Splatoon 2 157 // Stub used by Splatoon 2
157 LOG_WARNING(Service_Friend, "(STUBBED) called"); 158 LOG_WARNING(Service_Friend, "(STUBBED) called");
158 IPC::ResponseBuilder rb{ctx, 2}; 159 IPC::ResponseBuilder rb{ctx, 2};
159 rb.Push(ResultSuccess); 160 rb.Push(ResultSuccess);
160 } 161 }
161 162
162 void UpdateUserPresence(Kernel::HLERequestContext& ctx) { 163 void UpdateUserPresence(HLERequestContext& ctx) {
163 // Stub used by Retro City Rampage 164 // Stub used by Retro City Rampage
164 LOG_WARNING(Service_Friend, "(STUBBED) called"); 165 LOG_WARNING(Service_Friend, "(STUBBED) called");
165 IPC::ResponseBuilder rb{ctx, 2}; 166 IPC::ResponseBuilder rb{ctx, 2};
166 rb.Push(ResultSuccess); 167 rb.Push(ResultSuccess);
167 } 168 }
168 169
169 void GetPlayHistoryRegistrationKey(Kernel::HLERequestContext& ctx) { 170 void GetPlayHistoryRegistrationKey(HLERequestContext& ctx) {
170 IPC::RequestParser rp{ctx}; 171 IPC::RequestParser rp{ctx};
171 const auto local_play = rp.Pop<bool>(); 172 const auto local_play = rp.Pop<bool>();
172 const auto uuid = rp.PopRaw<Common::UUID>(); 173 const auto uuid = rp.PopRaw<Common::UUID>();
@@ -178,7 +179,7 @@ private:
178 rb.Push(ResultSuccess); 179 rb.Push(ResultSuccess);
179 } 180 }
180 181
181 void GetFriendList(Kernel::HLERequestContext& ctx) { 182 void GetFriendList(HLERequestContext& ctx) {
182 IPC::RequestParser rp{ctx}; 183 IPC::RequestParser rp{ctx};
183 const auto friend_offset = rp.Pop<u32>(); 184 const auto friend_offset = rp.Pop<u32>();
184 const auto uuid = rp.PopRaw<Common::UUID>(); 185 const auto uuid = rp.PopRaw<Common::UUID>();
@@ -194,7 +195,7 @@ private:
194 // TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId" 195 // TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId"
195 } 196 }
196 197
197 void CheckFriendListAvailability(Kernel::HLERequestContext& ctx) { 198 void CheckFriendListAvailability(HLERequestContext& ctx) {
198 IPC::RequestParser rp{ctx}; 199 IPC::RequestParser rp{ctx};
199 const auto uuid{rp.PopRaw<Common::UUID>()}; 200 const auto uuid{rp.PopRaw<Common::UUID>()};
200 201
@@ -233,7 +234,7 @@ public:
233 } 234 }
234 235
235private: 236private:
236 void GetEvent(Kernel::HLERequestContext& ctx) { 237 void GetEvent(HLERequestContext& ctx) {
237 LOG_DEBUG(Service_Friend, "called"); 238 LOG_DEBUG(Service_Friend, "called");
238 239
239 IPC::ResponseBuilder rb{ctx, 2, 1}; 240 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -241,7 +242,7 @@ private:
241 rb.PushCopyObjects(notification_event->GetReadableEvent()); 242 rb.PushCopyObjects(notification_event->GetReadableEvent());
242 } 243 }
243 244
244 void Clear(Kernel::HLERequestContext& ctx) { 245 void Clear(HLERequestContext& ctx) {
245 LOG_DEBUG(Service_Friend, "called"); 246 LOG_DEBUG(Service_Friend, "called");
246 while (!notifications.empty()) { 247 while (!notifications.empty()) {
247 notifications.pop(); 248 notifications.pop();
@@ -252,13 +253,13 @@ private:
252 rb.Push(ResultSuccess); 253 rb.Push(ResultSuccess);
253 } 254 }
254 255
255 void Pop(Kernel::HLERequestContext& ctx) { 256 void Pop(HLERequestContext& ctx) {
256 LOG_DEBUG(Service_Friend, "called"); 257 LOG_DEBUG(Service_Friend, "called");
257 258
258 if (notifications.empty()) { 259 if (notifications.empty()) {
259 LOG_ERROR(Service_Friend, "No notifications in queue!"); 260 LOG_ERROR(Service_Friend, "No notifications in queue!");
260 IPC::ResponseBuilder rb{ctx, 2}; 261 IPC::ResponseBuilder rb{ctx, 2};
261 rb.Push(ERR_NO_NOTIFICATIONS); 262 rb.Push(Account::ResultNoNotifications);
262 return; 263 return;
263 } 264 }
264 265
@@ -311,14 +312,14 @@ private:
311 States states{}; 312 States states{};
312}; 313};
313 314
314void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) { 315void Module::Interface::CreateFriendService(HLERequestContext& ctx) {
315 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 316 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
316 rb.Push(ResultSuccess); 317 rb.Push(ResultSuccess);
317 rb.PushIpcInterface<IFriendService>(system); 318 rb.PushIpcInterface<IFriendService>(system);
318 LOG_DEBUG(Service_Friend, "called"); 319 LOG_DEBUG(Service_Friend, "called");
319} 320}
320 321
321void Module::Interface::CreateNotificationService(Kernel::HLERequestContext& ctx) { 322void Module::Interface::CreateNotificationService(HLERequestContext& ctx) {
322 IPC::RequestParser rp{ctx}; 323 IPC::RequestParser rp{ctx};
323 auto uuid = rp.PopRaw<Common::UUID>(); 324 auto uuid = rp.PopRaw<Common::UUID>();
324 325
@@ -335,13 +336,22 @@ Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& syst
335 336
336Module::Interface::~Interface() = default; 337Module::Interface::~Interface() = default;
337 338
338void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 339void LoopProcess(Core::System& system) {
340 auto server_manager = std::make_unique<ServerManager>(system);
339 auto module = std::make_shared<Module>(); 341 auto module = std::make_shared<Module>();
340 std::make_shared<Friend>(module, system, "friend:a")->InstallAsService(service_manager); 342
341 std::make_shared<Friend>(module, system, "friend:m")->InstallAsService(service_manager); 343 server_manager->RegisterNamedService("friend:a",
342 std::make_shared<Friend>(module, system, "friend:s")->InstallAsService(service_manager); 344 std::make_shared<Friend>(module, system, "friend:a"));
343 std::make_shared<Friend>(module, system, "friend:u")->InstallAsService(service_manager); 345 server_manager->RegisterNamedService("friend:m",
344 std::make_shared<Friend>(module, system, "friend:v")->InstallAsService(service_manager); 346 std::make_shared<Friend>(module, system, "friend:m"));
347 server_manager->RegisterNamedService("friend:s",
348 std::make_shared<Friend>(module, system, "friend:s"));
349 server_manager->RegisterNamedService("friend:u",
350 std::make_shared<Friend>(module, system, "friend:u"));
351 server_manager->RegisterNamedService("friend:v",
352 std::make_shared<Friend>(module, system, "friend:v"));
353
354 ServerManager::RunServer(std::move(server_manager));
345} 355}
346 356
347} // namespace Service::Friend 357} // namespace Service::Friend
diff --git a/src/core/hle/service/friend/friend.h b/src/core/hle/service/friend/friend.h
index 444da8b35..2824dc786 100644
--- a/src/core/hle/service/friend/friend.h
+++ b/src/core/hle/service/friend/friend.h
@@ -19,15 +19,14 @@ public:
19 const char* name); 19 const char* name);
20 ~Interface() override; 20 ~Interface() override;
21 21
22 void CreateFriendService(Kernel::HLERequestContext& ctx); 22 void CreateFriendService(HLERequestContext& ctx);
23 void CreateNotificationService(Kernel::HLERequestContext& ctx); 23 void CreateNotificationService(HLERequestContext& ctx);
24 24
25 protected: 25 protected:
26 std::shared_ptr<Module> module; 26 std::shared_ptr<Module> module;
27 }; 27 };
28}; 28};
29 29
30/// Registers all Friend services with the specified service manager. 30void LoopProcess(Core::System& system);
31void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
32 31
33} // namespace Service::Friend 32} // namespace Service::Friend
diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp
index ce21b69e3..929dcca0d 100644
--- a/src/core/hle/service/glue/arp.cpp
+++ b/src/core/hle/service/glue/arp.cpp
@@ -5,12 +5,12 @@
5 5
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core.h" 7#include "core/core.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/k_process.h" 8#include "core/hle/kernel/k_process.h"
10#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
11#include "core/hle/service/glue/arp.h" 10#include "core/hle/service/glue/arp.h"
12#include "core/hle/service/glue/errors.h" 11#include "core/hle/service/glue/errors.h"
13#include "core/hle/service/glue/glue_manager.h" 12#include "core/hle/service/glue/glue_manager.h"
13#include "core/hle/service/ipc_helpers.h"
14 14
15namespace Service::Glue { 15namespace Service::Glue {
16 16
@@ -51,7 +51,7 @@ ARP_R::ARP_R(Core::System& system_, const ARPManager& manager_)
51 51
52ARP_R::~ARP_R() = default; 52ARP_R::~ARP_R() = default;
53 53
54void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { 54void ARP_R::GetApplicationLaunchProperty(HLERequestContext& ctx) {
55 IPC::RequestParser rp{ctx}; 55 IPC::RequestParser rp{ctx};
56 const auto process_id = rp.PopRaw<u64>(); 56 const auto process_id = rp.PopRaw<u64>();
57 57
@@ -61,7 +61,7 @@ void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) {
61 if (!title_id.has_value()) { 61 if (!title_id.has_value()) {
62 LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); 62 LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!");
63 IPC::ResponseBuilder rb{ctx, 2}; 63 IPC::ResponseBuilder rb{ctx, 2};
64 rb.Push(ERR_NOT_REGISTERED); 64 rb.Push(Glue::ResultProcessIdNotRegistered);
65 return; 65 return;
66 } 66 }
67 67
@@ -79,7 +79,7 @@ void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) {
79 rb.PushRaw(*res); 79 rb.PushRaw(*res);
80} 80}
81 81
82void ARP_R::GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestContext& ctx) { 82void ARP_R::GetApplicationLaunchPropertyWithApplicationId(HLERequestContext& ctx) {
83 IPC::RequestParser rp{ctx}; 83 IPC::RequestParser rp{ctx};
84 const auto title_id = rp.PopRaw<u64>(); 84 const auto title_id = rp.PopRaw<u64>();
85 85
@@ -99,7 +99,7 @@ void ARP_R::GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestCont
99 rb.PushRaw(*res); 99 rb.PushRaw(*res);
100} 100}
101 101
102void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) { 102void ARP_R::GetApplicationControlProperty(HLERequestContext& ctx) {
103 IPC::RequestParser rp{ctx}; 103 IPC::RequestParser rp{ctx};
104 const auto process_id = rp.PopRaw<u64>(); 104 const auto process_id = rp.PopRaw<u64>();
105 105
@@ -109,7 +109,7 @@ void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) {
109 if (!title_id.has_value()) { 109 if (!title_id.has_value()) {
110 LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); 110 LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!");
111 IPC::ResponseBuilder rb{ctx, 2}; 111 IPC::ResponseBuilder rb{ctx, 2};
112 rb.Push(ERR_NOT_REGISTERED); 112 rb.Push(Glue::ResultProcessIdNotRegistered);
113 return; 113 return;
114 } 114 }
115 115
@@ -128,7 +128,7 @@ void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) {
128 rb.Push(ResultSuccess); 128 rb.Push(ResultSuccess);
129} 129}
130 130
131void ARP_R::GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestContext& ctx) { 131void ARP_R::GetApplicationControlPropertyWithApplicationId(HLERequestContext& ctx) {
132 IPC::RequestParser rp{ctx}; 132 IPC::RequestParser rp{ctx};
133 const auto title_id = rp.PopRaw<u64>(); 133 const auto title_id = rp.PopRaw<u64>();
134 134
@@ -169,7 +169,7 @@ public:
169 } 169 }
170 170
171private: 171private:
172 void Issue(Kernel::HLERequestContext& ctx) { 172 void Issue(HLERequestContext& ctx) {
173 IPC::RequestParser rp{ctx}; 173 IPC::RequestParser rp{ctx};
174 const auto process_id = rp.PopRaw<u64>(); 174 const auto process_id = rp.PopRaw<u64>();
175 175
@@ -178,7 +178,7 @@ private:
178 if (process_id == 0) { 178 if (process_id == 0) {
179 LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); 179 LOG_ERROR(Service_ARP, "Must have non-zero process ID!");
180 IPC::ResponseBuilder rb{ctx, 2}; 180 IPC::ResponseBuilder rb{ctx, 2};
181 rb.Push(ERR_INVALID_PROCESS_ID); 181 rb.Push(Glue::ResultInvalidProcessId);
182 return; 182 return;
183 } 183 }
184 184
@@ -186,7 +186,7 @@ private:
186 LOG_ERROR(Service_ARP, 186 LOG_ERROR(Service_ARP,
187 "Attempted to issue registrar, but registrar is already issued!"); 187 "Attempted to issue registrar, but registrar is already issued!");
188 IPC::ResponseBuilder rb{ctx, 2}; 188 IPC::ResponseBuilder rb{ctx, 2};
189 rb.Push(ERR_INVALID_ACCESS); 189 rb.Push(Glue::ResultAlreadyBound);
190 return; 190 return;
191 } 191 }
192 192
@@ -197,7 +197,7 @@ private:
197 rb.Push(ResultSuccess); 197 rb.Push(ResultSuccess);
198 } 198 }
199 199
200 void SetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { 200 void SetApplicationLaunchProperty(HLERequestContext& ctx) {
201 LOG_DEBUG(Service_ARP, "called"); 201 LOG_DEBUG(Service_ARP, "called");
202 202
203 if (issued) { 203 if (issued) {
@@ -205,7 +205,7 @@ private:
205 Service_ARP, 205 Service_ARP,
206 "Attempted to set application launch property, but registrar is already issued!"); 206 "Attempted to set application launch property, but registrar is already issued!");
207 IPC::ResponseBuilder rb{ctx, 2}; 207 IPC::ResponseBuilder rb{ctx, 2};
208 rb.Push(ERR_INVALID_ACCESS); 208 rb.Push(Glue::ResultAlreadyBound);
209 return; 209 return;
210 } 210 }
211 211
@@ -216,7 +216,7 @@ private:
216 rb.Push(ResultSuccess); 216 rb.Push(ResultSuccess);
217 } 217 }
218 218
219 void SetApplicationControlProperty(Kernel::HLERequestContext& ctx) { 219 void SetApplicationControlProperty(HLERequestContext& ctx) {
220 LOG_DEBUG(Service_ARP, "called"); 220 LOG_DEBUG(Service_ARP, "called");
221 221
222 if (issued) { 222 if (issued) {
@@ -224,7 +224,7 @@ private:
224 Service_ARP, 224 Service_ARP,
225 "Attempted to set application control property, but registrar is already issued!"); 225 "Attempted to set application control property, but registrar is already issued!");
226 IPC::ResponseBuilder rb{ctx, 2}; 226 IPC::ResponseBuilder rb{ctx, 2};
227 rb.Push(ERR_INVALID_ACCESS); 227 rb.Push(Glue::ResultAlreadyBound);
228 return; 228 return;
229 } 229 }
230 230
@@ -256,14 +256,14 @@ ARP_W::ARP_W(Core::System& system_, ARPManager& manager_)
256 256
257ARP_W::~ARP_W() = default; 257ARP_W::~ARP_W() = default;
258 258
259void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) { 259void ARP_W::AcquireRegistrar(HLERequestContext& ctx) {
260 LOG_DEBUG(Service_ARP, "called"); 260 LOG_DEBUG(Service_ARP, "called");
261 261
262 registrar = std::make_shared<IRegistrar>( 262 registrar = std::make_shared<IRegistrar>(
263 system, [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) { 263 system, [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) {
264 const auto res = GetTitleIDForProcessID(system, process_id); 264 const auto res = GetTitleIDForProcessID(system, process_id);
265 if (!res.has_value()) { 265 if (!res.has_value()) {
266 return ERR_NOT_REGISTERED; 266 return Glue::ResultProcessIdNotRegistered;
267 } 267 }
268 268
269 return manager.Register(*res, launch, std::move(control)); 269 return manager.Register(*res, launch, std::move(control));
@@ -274,7 +274,7 @@ void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) {
274 rb.PushIpcInterface(registrar); 274 rb.PushIpcInterface(registrar);
275} 275}
276 276
277void ARP_W::UnregisterApplicationInstance(Kernel::HLERequestContext& ctx) { 277void ARP_W::UnregisterApplicationInstance(HLERequestContext& ctx) {
278 IPC::RequestParser rp{ctx}; 278 IPC::RequestParser rp{ctx};
279 const auto process_id = rp.PopRaw<u64>(); 279 const auto process_id = rp.PopRaw<u64>();
280 280
@@ -283,7 +283,7 @@ void ARP_W::UnregisterApplicationInstance(Kernel::HLERequestContext& ctx) {
283 if (process_id == 0) { 283 if (process_id == 0) {
284 LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); 284 LOG_ERROR(Service_ARP, "Must have non-zero process ID!");
285 IPC::ResponseBuilder rb{ctx, 2}; 285 IPC::ResponseBuilder rb{ctx, 2};
286 rb.Push(ERR_INVALID_PROCESS_ID); 286 rb.Push(Glue::ResultInvalidProcessId);
287 return; 287 return;
288 } 288 }
289 289
@@ -292,7 +292,7 @@ void ARP_W::UnregisterApplicationInstance(Kernel::HLERequestContext& ctx) {
292 if (!title_id.has_value()) { 292 if (!title_id.has_value()) {
293 LOG_ERROR(Service_ARP, "No title ID for process ID!"); 293 LOG_ERROR(Service_ARP, "No title ID for process ID!");
294 IPC::ResponseBuilder rb{ctx, 2}; 294 IPC::ResponseBuilder rb{ctx, 2};
295 rb.Push(ERR_NOT_REGISTERED); 295 rb.Push(Glue::ResultProcessIdNotRegistered);
296 return; 296 return;
297 } 297 }
298 298
diff --git a/src/core/hle/service/glue/arp.h b/src/core/hle/service/glue/arp.h
index 06c992e88..5bce80175 100644
--- a/src/core/hle/service/glue/arp.h
+++ b/src/core/hle/service/glue/arp.h
@@ -16,10 +16,10 @@ public:
16 ~ARP_R() override; 16 ~ARP_R() override;
17 17
18private: 18private:
19 void GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx); 19 void GetApplicationLaunchProperty(HLERequestContext& ctx);
20 void GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestContext& ctx); 20 void GetApplicationLaunchPropertyWithApplicationId(HLERequestContext& ctx);
21 void GetApplicationControlProperty(Kernel::HLERequestContext& ctx); 21 void GetApplicationControlProperty(HLERequestContext& ctx);
22 void GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestContext& ctx); 22 void GetApplicationControlPropertyWithApplicationId(HLERequestContext& ctx);
23 23
24 const ARPManager& manager; 24 const ARPManager& manager;
25}; 25};
@@ -30,8 +30,8 @@ public:
30 ~ARP_W() override; 30 ~ARP_W() override;
31 31
32private: 32private:
33 void AcquireRegistrar(Kernel::HLERequestContext& ctx); 33 void AcquireRegistrar(HLERequestContext& ctx);
34 void UnregisterApplicationInstance(Kernel::HLERequestContext& ctx); 34 void UnregisterApplicationInstance(HLERequestContext& ctx);
35 35
36 ARPManager& manager; 36 ARPManager& manager;
37 std::shared_ptr<IRegistrar> registrar; 37 std::shared_ptr<IRegistrar> registrar;
diff --git a/src/core/hle/service/glue/bgtc.cpp b/src/core/hle/service/glue/bgtc.cpp
index 3248091c3..ae22ac4f7 100644
--- a/src/core/hle/service/glue/bgtc.cpp
+++ b/src/core/hle/service/glue/bgtc.cpp
@@ -3,8 +3,8 @@
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/ipc_helpers.h"
7#include "core/hle/service/glue/bgtc.h" 6#include "core/hle/service/glue/bgtc.h"
7#include "core/hle/service/ipc_helpers.h"
8 8
9namespace Service::Glue { 9namespace Service::Glue {
10 10
@@ -20,7 +20,7 @@ BGTC_T::BGTC_T(Core::System& system_) : ServiceFramework{system_, "bgtc:t"} {
20 20
21BGTC_T::~BGTC_T() = default; 21BGTC_T::~BGTC_T() = default;
22 22
23void BGTC_T::OpenTaskService(Kernel::HLERequestContext& ctx) { 23void BGTC_T::OpenTaskService(HLERequestContext& ctx) {
24 LOG_DEBUG(Service_BGTC, "called"); 24 LOG_DEBUG(Service_BGTC, "called");
25 25
26 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 26 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
diff --git a/src/core/hle/service/glue/bgtc.h b/src/core/hle/service/glue/bgtc.h
index d6e2baec1..5a5d9c9a7 100644
--- a/src/core/hle/service/glue/bgtc.h
+++ b/src/core/hle/service/glue/bgtc.h
@@ -16,7 +16,7 @@ public:
16 explicit BGTC_T(Core::System& system_); 16 explicit BGTC_T(Core::System& system_);
17 ~BGTC_T() override; 17 ~BGTC_T() override;
18 18
19 void OpenTaskService(Kernel::HLERequestContext& ctx); 19 void OpenTaskService(HLERequestContext& ctx);
20}; 20};
21 21
22class ITaskService final : public ServiceFramework<ITaskService> { 22class ITaskService final : public ServiceFramework<ITaskService> {
diff --git a/src/core/hle/service/glue/errors.h b/src/core/hle/service/glue/errors.h
index d4ce7f44e..30feaa5c0 100644
--- a/src/core/hle/service/glue/errors.h
+++ b/src/core/hle/service/glue/errors.h
@@ -7,9 +7,8 @@
7 7
8namespace Service::Glue { 8namespace Service::Glue {
9 9
10constexpr Result ERR_INVALID_RESOURCE{ErrorModule::ARP, 30}; 10constexpr Result ResultInvalidProcessId{ErrorModule::ARP, 31};
11constexpr Result ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 31}; 11constexpr Result ResultAlreadyBound{ErrorModule::ARP, 42};
12constexpr Result ERR_INVALID_ACCESS{ErrorModule::ARP, 42}; 12constexpr Result ResultProcessIdNotRegistered{ErrorModule::ARP, 102};
13constexpr Result ERR_NOT_REGISTERED{ErrorModule::ARP, 102};
14 13
15} // namespace Service::Glue 14} // namespace Service::Glue
diff --git a/src/core/hle/service/glue/glue.cpp b/src/core/hle/service/glue/glue.cpp
index 717f2562b..993c3d21d 100644
--- a/src/core/hle/service/glue/glue.cpp
+++ b/src/core/hle/service/glue/glue.cpp
@@ -8,25 +8,30 @@
8#include "core/hle/service/glue/ectx.h" 8#include "core/hle/service/glue/ectx.h"
9#include "core/hle/service/glue/glue.h" 9#include "core/hle/service/glue/glue.h"
10#include "core/hle/service/glue/notif.h" 10#include "core/hle/service/glue/notif.h"
11#include "core/hle/service/server_manager.h"
11 12
12namespace Service::Glue { 13namespace Service::Glue {
13 14
14void InstallInterfaces(Core::System& system) { 15void LoopProcess(Core::System& system) {
16 auto server_manager = std::make_unique<ServerManager>(system);
17
15 // ARP 18 // ARP
16 std::make_shared<ARP_R>(system, system.GetARPManager()) 19 server_manager->RegisterNamedService("arp:r",
17 ->InstallAsService(system.ServiceManager()); 20 std::make_shared<ARP_R>(system, system.GetARPManager()));
18 std::make_shared<ARP_W>(system, system.GetARPManager()) 21 server_manager->RegisterNamedService("arp:w",
19 ->InstallAsService(system.ServiceManager()); 22 std::make_shared<ARP_W>(system, system.GetARPManager()));
20 23
21 // BackGround Task Controller 24 // BackGround Task Controller
22 std::make_shared<BGTC_T>(system)->InstallAsService(system.ServiceManager()); 25 server_manager->RegisterNamedService("bgtc:t", std::make_shared<BGTC_T>(system));
23 std::make_shared<BGTC_SC>(system)->InstallAsService(system.ServiceManager()); 26 server_manager->RegisterNamedService("bgtc:sc", std::make_shared<BGTC_SC>(system));
24 27
25 // Error Context 28 // Error Context
26 std::make_shared<ECTX_AW>(system)->InstallAsService(system.ServiceManager()); 29 server_manager->RegisterNamedService("ectx:aw", std::make_shared<ECTX_AW>(system));
27 30
28 // Notification Services for application 31 // Notification Services for application
29 std::make_shared<NOTIF_A>(system)->InstallAsService(system.ServiceManager()); 32 server_manager->RegisterNamedService("notif:a", std::make_shared<NOTIF_A>(system));
33
34 ServerManager::RunServer(std::move(server_manager));
30} 35}
31 36
32} // namespace Service::Glue 37} // namespace Service::Glue
diff --git a/src/core/hle/service/glue/glue.h b/src/core/hle/service/glue/glue.h
index ae7c6d235..2a906f5ad 100644
--- a/src/core/hle/service/glue/glue.h
+++ b/src/core/hle/service/glue/glue.h
@@ -9,7 +9,6 @@ class System;
9 9
10namespace Service::Glue { 10namespace Service::Glue {
11 11
12/// Registers all Glue services with the specified service manager. 12void LoopProcess(Core::System& system);
13void InstallInterfaces(Core::System& system);
14 13
15} // namespace Service::Glue 14} // namespace Service::Glue
diff --git a/src/core/hle/service/glue/glue_manager.cpp b/src/core/hle/service/glue/glue_manager.cpp
index 8a654cdca..4bf67921b 100644
--- a/src/core/hle/service/glue/glue_manager.cpp
+++ b/src/core/hle/service/glue/glue_manager.cpp
@@ -17,12 +17,12 @@ ARPManager::~ARPManager() = default;
17 17
18ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id) const { 18ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id) const {
19 if (title_id == 0) { 19 if (title_id == 0) {
20 return ERR_INVALID_PROCESS_ID; 20 return Glue::ResultInvalidProcessId;
21 } 21 }
22 22
23 const auto iter = entries.find(title_id); 23 const auto iter = entries.find(title_id);
24 if (iter == entries.end()) { 24 if (iter == entries.end()) {
25 return ERR_NOT_REGISTERED; 25 return Glue::ResultProcessIdNotRegistered;
26 } 26 }
27 27
28 return iter->second.launch; 28 return iter->second.launch;
@@ -30,12 +30,12 @@ ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id)
30 30
31ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const { 31ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const {
32 if (title_id == 0) { 32 if (title_id == 0) {
33 return ERR_INVALID_PROCESS_ID; 33 return Glue::ResultInvalidProcessId;
34 } 34 }
35 35
36 const auto iter = entries.find(title_id); 36 const auto iter = entries.find(title_id);
37 if (iter == entries.end()) { 37 if (iter == entries.end()) {
38 return ERR_NOT_REGISTERED; 38 return Glue::ResultProcessIdNotRegistered;
39 } 39 }
40 40
41 return iter->second.control; 41 return iter->second.control;
@@ -44,12 +44,12 @@ ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const {
44Result ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, 44Result ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch,
45 std::vector<u8> control) { 45 std::vector<u8> control) {
46 if (title_id == 0) { 46 if (title_id == 0) {
47 return ERR_INVALID_PROCESS_ID; 47 return Glue::ResultInvalidProcessId;
48 } 48 }
49 49
50 const auto iter = entries.find(title_id); 50 const auto iter = entries.find(title_id);
51 if (iter != entries.end()) { 51 if (iter != entries.end()) {
52 return ERR_INVALID_ACCESS; 52 return Glue::ResultAlreadyBound;
53 } 53 }
54 54
55 entries.insert_or_assign(title_id, MapEntry{launch, std::move(control)}); 55 entries.insert_or_assign(title_id, MapEntry{launch, std::move(control)});
@@ -58,12 +58,12 @@ Result ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch,
58 58
59Result ARPManager::Unregister(u64 title_id) { 59Result ARPManager::Unregister(u64 title_id) {
60 if (title_id == 0) { 60 if (title_id == 0) {
61 return ERR_INVALID_PROCESS_ID; 61 return Glue::ResultInvalidProcessId;
62 } 62 }
63 63
64 const auto iter = entries.find(title_id); 64 const auto iter = entries.find(title_id);
65 if (iter == entries.end()) { 65 if (iter == entries.end()) {
66 return ERR_NOT_REGISTERED; 66 return Glue::ResultProcessIdNotRegistered;
67 } 67 }
68 68
69 entries.erase(iter); 69 entries.erase(iter);
diff --git a/src/core/hle/service/glue/glue_manager.h b/src/core/hle/service/glue/glue_manager.h
index cd0b092ac..1cf53d9d9 100644
--- a/src/core/hle/service/glue/glue_manager.h
+++ b/src/core/hle/service/glue/glue_manager.h
@@ -30,23 +30,23 @@ public:
30 ~ARPManager(); 30 ~ARPManager();
31 31
32 // Returns the ApplicationLaunchProperty corresponding to the provided title ID if it was 32 // Returns the ApplicationLaunchProperty corresponding to the provided title ID if it was
33 // previously registered, otherwise ERR_NOT_REGISTERED if it was never registered or 33 // previously registered, otherwise ResultProcessIdNotRegistered if it was never registered or
34 // ERR_INVALID_PROCESS_ID if the title ID is 0. 34 // ResultInvalidProcessId if the title ID is 0.
35 ResultVal<ApplicationLaunchProperty> GetLaunchProperty(u64 title_id) const; 35 ResultVal<ApplicationLaunchProperty> GetLaunchProperty(u64 title_id) const;
36 36
37 // Returns a vector of the raw bytes of NACP data (necessarily 0x4000 in size) corresponding to 37 // Returns a vector of the raw bytes of NACP data (necessarily 0x4000 in size) corresponding to
38 // the provided title ID if it was previously registered, otherwise ERR_NOT_REGISTERED if it was 38 // the provided title ID if it was previously registered, otherwise ResultProcessIdNotRegistered
39 // never registered or ERR_INVALID_PROCESS_ID if the title ID is 0. 39 // if it was never registered or ResultInvalidProcessId if the title ID is 0.
40 ResultVal<std::vector<u8>> GetControlProperty(u64 title_id) const; 40 ResultVal<std::vector<u8>> GetControlProperty(u64 title_id) const;
41 41
42 // Adds a new entry to the internal database with the provided parameters, returning 42 // Adds a new entry to the internal database with the provided parameters, returning
43 // ERR_INVALID_ACCESS if attempting to re-register a title ID without an intermediate Unregister 43 // ResultProcessIdNotRegistered if attempting to re-register a title ID without an intermediate
44 // step, and ERR_INVALID_PROCESS_ID if the title ID is 0. 44 // Unregister step, and ResultInvalidProcessId if the title ID is 0.
45 Result Register(u64 title_id, ApplicationLaunchProperty launch, std::vector<u8> control); 45 Result Register(u64 title_id, ApplicationLaunchProperty launch, std::vector<u8> control);
46 46
47 // Removes the registration for the provided title ID from the database, returning 47 // Removes the registration for the provided title ID from the database, returning
48 // ERR_NOT_REGISTERED if it doesn't exist in the database and ERR_INVALID_PROCESS_ID if the 48 // ResultProcessIdNotRegistered if it doesn't exist in the database and ResultInvalidProcessId
49 // title ID is 0. 49 // if the title ID is 0.
50 Result Unregister(u64 title_id); 50 Result Unregister(u64 title_id);
51 51
52 // Removes all entries from the database, always succeeds. Should only be used when resetting 52 // Removes all entries from the database, always succeeds. Should only be used when resetting
diff --git a/src/core/hle/service/glue/notif.cpp b/src/core/hle/service/glue/notif.cpp
index 3ace2dabd..fec4ad86c 100644
--- a/src/core/hle/service/glue/notif.cpp
+++ b/src/core/hle/service/glue/notif.cpp
@@ -6,8 +6,8 @@
6 6
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "core/hle/ipc_helpers.h"
10#include "core/hle/service/glue/notif.h" 9#include "core/hle/service/glue/notif.h"
10#include "core/hle/service/ipc_helpers.h"
11 11
12namespace Service::Glue { 12namespace Service::Glue {
13 13
@@ -28,7 +28,7 @@ NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} {
28 28
29NOTIF_A::~NOTIF_A() = default; 29NOTIF_A::~NOTIF_A() = default;
30 30
31void NOTIF_A::RegisterAlarmSetting(Kernel::HLERequestContext& ctx) { 31void NOTIF_A::RegisterAlarmSetting(HLERequestContext& ctx) {
32 const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); 32 const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0);
33 const auto application_parameter_size = ctx.GetReadBufferSize(1); 33 const auto application_parameter_size = ctx.GetReadBufferSize(1);
34 34
@@ -63,7 +63,7 @@ void NOTIF_A::RegisterAlarmSetting(Kernel::HLERequestContext& ctx) {
63 rb.Push(new_alarm.alarm_setting_id); 63 rb.Push(new_alarm.alarm_setting_id);
64} 64}
65 65
66void NOTIF_A::UpdateAlarmSetting(Kernel::HLERequestContext& ctx) { 66void NOTIF_A::UpdateAlarmSetting(HLERequestContext& ctx) {
67 const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); 67 const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0);
68 const auto application_parameter_size = ctx.GetReadBufferSize(1); 68 const auto application_parameter_size = ctx.GetReadBufferSize(1);
69 69
@@ -91,7 +91,7 @@ void NOTIF_A::UpdateAlarmSetting(Kernel::HLERequestContext& ctx) {
91 rb.Push(ResultSuccess); 91 rb.Push(ResultSuccess);
92} 92}
93 93
94void NOTIF_A::ListAlarmSettings(Kernel::HLERequestContext& ctx) { 94void NOTIF_A::ListAlarmSettings(HLERequestContext& ctx) {
95 LOG_INFO(Service_NOTIF, "called, alarm_count={}", alarms.size()); 95 LOG_INFO(Service_NOTIF, "called, alarm_count={}", alarms.size());
96 96
97 // TODO: Only return alarms of this game id 97 // TODO: Only return alarms of this game id
@@ -102,7 +102,7 @@ void NOTIF_A::ListAlarmSettings(Kernel::HLERequestContext& ctx) {
102 rb.Push(static_cast<u32>(alarms.size())); 102 rb.Push(static_cast<u32>(alarms.size()));
103} 103}
104 104
105void NOTIF_A::LoadApplicationParameter(Kernel::HLERequestContext& ctx) { 105void NOTIF_A::LoadApplicationParameter(HLERequestContext& ctx) {
106 IPC::RequestParser rp{ctx}; 106 IPC::RequestParser rp{ctx};
107 const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; 107 const auto alarm_setting_id{rp.Pop<AlarmSettingId>()};
108 108
@@ -126,7 +126,7 @@ void NOTIF_A::LoadApplicationParameter(Kernel::HLERequestContext& ctx) {
126 rb.Push(static_cast<u32>(application_parameter.size())); 126 rb.Push(static_cast<u32>(application_parameter.size()));
127} 127}
128 128
129void NOTIF_A::DeleteAlarmSetting(Kernel::HLERequestContext& ctx) { 129void NOTIF_A::DeleteAlarmSetting(HLERequestContext& ctx) {
130 IPC::RequestParser rp{ctx}; 130 IPC::RequestParser rp{ctx};
131 const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; 131 const auto alarm_setting_id{rp.Pop<AlarmSettingId>()};
132 132
@@ -140,7 +140,7 @@ void NOTIF_A::DeleteAlarmSetting(Kernel::HLERequestContext& ctx) {
140 rb.Push(ResultSuccess); 140 rb.Push(ResultSuccess);
141} 141}
142 142
143void NOTIF_A::Initialize(Kernel::HLERequestContext& ctx) { 143void NOTIF_A::Initialize(HLERequestContext& ctx) {
144 // TODO: Load previous alarms from config 144 // TODO: Load previous alarms from config
145 145
146 LOG_WARNING(Service_NOTIF, "(STUBBED) called"); 146 LOG_WARNING(Service_NOTIF, "(STUBBED) called");
diff --git a/src/core/hle/service/glue/notif.h b/src/core/hle/service/glue/notif.h
index 4467e1f35..b1187f3a3 100644
--- a/src/core/hle/service/glue/notif.h
+++ b/src/core/hle/service/glue/notif.h
@@ -56,12 +56,12 @@ private:
56 }; 56 };
57 static_assert(sizeof(AlarmSetting) == 0x40, "AlarmSetting is an invalid size"); 57 static_assert(sizeof(AlarmSetting) == 0x40, "AlarmSetting is an invalid size");
58 58
59 void RegisterAlarmSetting(Kernel::HLERequestContext& ctx); 59 void RegisterAlarmSetting(HLERequestContext& ctx);
60 void UpdateAlarmSetting(Kernel::HLERequestContext& ctx); 60 void UpdateAlarmSetting(HLERequestContext& ctx);
61 void ListAlarmSettings(Kernel::HLERequestContext& ctx); 61 void ListAlarmSettings(HLERequestContext& ctx);
62 void LoadApplicationParameter(Kernel::HLERequestContext& ctx); 62 void LoadApplicationParameter(HLERequestContext& ctx);
63 void DeleteAlarmSetting(Kernel::HLERequestContext& ctx); 63 void DeleteAlarmSetting(HLERequestContext& ctx);
64 void Initialize(Kernel::HLERequestContext& ctx); 64 void Initialize(HLERequestContext& ctx);
65 65
66 std::vector<AlarmSetting>::iterator GetAlarmFromId(AlarmSettingId alarm_setting_id); 66 std::vector<AlarmSetting>::iterator GetAlarmFromId(AlarmSettingId alarm_setting_id);
67 67
diff --git a/src/core/hle/service/grc/grc.cpp b/src/core/hle/service/grc/grc.cpp
index 4b684f6d0..64275da36 100644
--- a/src/core/hle/service/grc/grc.cpp
+++ b/src/core/hle/service/grc/grc.cpp
@@ -4,8 +4,8 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/grc/grc.h" 6#include "core/hle/service/grc/grc.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::GRC { 10namespace Service::GRC {
11 11
@@ -26,8 +26,11 @@ public:
26 } 26 }
27}; 27};
28 28
29void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 29void LoopProcess(Core::System& system) {
30 std::make_shared<GRC>(system)->InstallAsService(sm); 30 auto server_manager = std::make_unique<ServerManager>(system);
31
32 server_manager->RegisterNamedService("grc:c", std::make_shared<GRC>(system));
33 ServerManager::RunServer(std::move(server_manager));
31} 34}
32 35
33} // namespace Service::GRC 36} // namespace Service::GRC
diff --git a/src/core/hle/service/grc/grc.h b/src/core/hle/service/grc/grc.h
index f8c2f8dab..a3f8a5b90 100644
--- a/src/core/hle/service/grc/grc.h
+++ b/src/core/hle/service/grc/grc.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::GRC { 10namespace Service::GRC {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::GRC 14} // namespace Service::GRC
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
index bb3cba910..478d38590 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
@@ -1,17 +1,18 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h"
4#include "core/core_timing.h" 5#include "core/core_timing.h"
5#include "core/hid/emulated_console.h" 6#include "core/hid/emulated_console.h"
6#include "core/hid/hid_core.h" 7#include "core/hid/hid_core.h"
7#include "core/hle/service/hid/controllers/console_sixaxis.h" 8#include "core/hle/service/hid/controllers/console_sixaxis.h"
9#include "core/memory.h"
8 10
9namespace Service::HID { 11namespace Service::HID {
10constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200; 12constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200;
11 13
12Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_, 14Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_)
13 u8* raw_shared_memory_) 15 : ControllerBase{system_.HIDCore()}, system{system_} {
14 : ControllerBase{hid_core_} {
15 console = hid_core.GetEmulatedConsole(); 16 console = hid_core.GetEmulatedConsole();
16 static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size, 17 static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size,
17 "ConsoleSharedMemory is bigger than the shared memory"); 18 "ConsoleSharedMemory is bigger than the shared memory");
@@ -26,7 +27,7 @@ void Controller_ConsoleSixAxis::OnInit() {}
26void Controller_ConsoleSixAxis::OnRelease() {} 27void Controller_ConsoleSixAxis::OnRelease() {}
27 28
28void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 29void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
29 if (!IsControllerActivated() || !is_transfer_memory_set) { 30 if (!IsControllerActivated() || transfer_memory == 0) {
30 seven_sixaxis_lifo.buffer_count = 0; 31 seven_sixaxis_lifo.buffer_count = 0;
31 seven_sixaxis_lifo.buffer_tail = 0; 32 seven_sixaxis_lifo.buffer_tail = 0;
32 return; 33 return;
@@ -59,11 +60,10 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti
59 60
60 // Update seven six axis transfer memory 61 // Update seven six axis transfer memory
61 seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); 62 seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
62 std::memcpy(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo)); 63 system.Memory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo));
63} 64}
64 65
65void Controller_ConsoleSixAxis::SetTransferMemoryPointer(u8* t_mem) { 66void Controller_ConsoleSixAxis::SetTransferMemoryAddress(VAddr t_mem) {
66 is_transfer_memory_set = true;
67 transfer_memory = t_mem; 67 transfer_memory = t_mem;
68} 68}
69 69
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/console_sixaxis.h
index 2fd11538f..8d3e4081b 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.h
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.h
@@ -10,6 +10,10 @@
10#include "core/hle/service/hid/controllers/controller_base.h" 10#include "core/hle/service/hid/controllers/controller_base.h"
11#include "core/hle/service/hid/ring_lifo.h" 11#include "core/hle/service/hid/ring_lifo.h"
12 12
13namespace Core {
14class System;
15} // namespace Core
16
13namespace Core::HID { 17namespace Core::HID {
14class EmulatedConsole; 18class EmulatedConsole;
15} // namespace Core::HID 19} // namespace Core::HID
@@ -17,7 +21,7 @@ class EmulatedConsole;
17namespace Service::HID { 21namespace Service::HID {
18class Controller_ConsoleSixAxis final : public ControllerBase { 22class Controller_ConsoleSixAxis final : public ControllerBase {
19public: 23public:
20 explicit Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 24 explicit Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_);
21 ~Controller_ConsoleSixAxis() override; 25 ~Controller_ConsoleSixAxis() override;
22 26
23 // Called when the controller is initialized 27 // Called when the controller is initialized
@@ -30,7 +34,7 @@ public:
30 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; 34 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
31 35
32 // Called on InitializeSevenSixAxisSensor 36 // Called on InitializeSevenSixAxisSensor
33 void SetTransferMemoryPointer(u8* t_mem); 37 void SetTransferMemoryAddress(VAddr t_mem);
34 38
35 // Called on ResetSevenSixAxisSensorTimestamp 39 // Called on ResetSevenSixAxisSensorTimestamp
36 void ResetTimestamp(); 40 void ResetTimestamp();
@@ -62,12 +66,13 @@ private:
62 static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size"); 66 static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size");
63 67
64 SevenSixAxisState next_seven_sixaxis_state{}; 68 SevenSixAxisState next_seven_sixaxis_state{};
65 u8* transfer_memory = nullptr; 69 VAddr transfer_memory{};
66 ConsoleSharedMemory* shared_memory = nullptr; 70 ConsoleSharedMemory* shared_memory = nullptr;
67 Core::HID::EmulatedConsole* console = nullptr; 71 Core::HID::EmulatedConsole* console = nullptr;
68 72
69 bool is_transfer_memory_set = false;
70 u64 last_saved_timestamp{}; 73 u64 last_saved_timestamp{};
71 u64 last_global_timestamp{}; 74 u64 last_global_timestamp{};
75
76 Core::System& system;
72}; 77};
73} // namespace Service::HID 78} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp
index 4564ea1e2..bce51285c 100644
--- a/src/core/hle/service/hid/controllers/palma.cpp
+++ b/src/core/hle/service/hid/controllers/palma.cpp
@@ -152,7 +152,7 @@ Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandl
152} 152}
153 153
154Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, 154Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
155 u8* t_mem, u64 size) { 155 VAddr t_mem, u64 size) {
156 if (handle.npad_id != active_handle.npad_id) { 156 if (handle.npad_id != active_handle.npad_id) {
157 return InvalidPalmaHandle; 157 return InvalidPalmaHandle;
158 } 158 }
diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h
index 1d7fc94e1..cf62f0dbc 100644
--- a/src/core/hle/service/hid/controllers/palma.h
+++ b/src/core/hle/service/hid/controllers/palma.h
@@ -125,7 +125,7 @@ public:
125 Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle); 125 Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle);
126 Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle); 126 Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle);
127 Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown); 127 Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown);
128 Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, u8* t_mem, 128 Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, VAddr t_mem,
129 u64 size); 129 u64 size);
130 Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle, 130 Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
131 s32 database_id_version_); 131 s32 database_id_version_);
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 8c99cec06..56c7275df 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -8,7 +8,6 @@
8#include "core/core.h" 8#include "core/core.h"
9#include "core/core_timing.h" 9#include "core/core_timing.h"
10#include "core/hid/hid_core.h" 10#include "core/hid/hid_core.h"
11#include "core/hle/ipc_helpers.h"
12#include "core/hle/kernel/k_readable_event.h" 11#include "core/hle/kernel/k_readable_event.h"
13#include "core/hle/kernel/k_shared_memory.h" 12#include "core/hle/kernel/k_shared_memory.h"
14#include "core/hle/kernel/k_transfer_memory.h" 13#include "core/hle/kernel/k_transfer_memory.h"
@@ -18,6 +17,8 @@
18#include "core/hle/service/hid/hidbus.h" 17#include "core/hle/service/hid/hidbus.h"
19#include "core/hle/service/hid/irs.h" 18#include "core/hle/service/hid/irs.h"
20#include "core/hle/service/hid/xcd.h" 19#include "core/hle/service/hid/xcd.h"
20#include "core/hle/service/ipc_helpers.h"
21#include "core/hle/service/server_manager.h"
21#include "core/memory.h" 22#include "core/memory.h"
22 23
23#include "core/hle/service/hid/controllers/console_sixaxis.h" 24#include "core/hle/service/hid/controllers/console_sixaxis.h"
@@ -137,7 +138,7 @@ IAppletResource::~IAppletResource() {
137 system.CoreTiming().UnscheduleEvent(motion_update_event, 0); 138 system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
138} 139}
139 140
140void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { 141void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
141 LOG_DEBUG(Service_HID, "called"); 142 LOG_DEBUG(Service_HID, "called");
142 143
143 IPC::ResponseBuilder rb{ctx, 2, 1}; 144 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -202,7 +203,7 @@ public:
202 } 203 }
203 204
204private: 205private:
205 void InitializeVibrationDevice(Kernel::HLERequestContext& ctx) { 206 void InitializeVibrationDevice(HLERequestContext& ctx) {
206 IPC::RequestParser rp{ctx}; 207 IPC::RequestParser rp{ctx};
207 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; 208 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
208 209
@@ -381,7 +382,7 @@ Hid::Hid(Core::System& system_)
381 382
382Hid::~Hid() = default; 383Hid::~Hid() = default;
383 384
384void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) { 385void Hid::CreateAppletResource(HLERequestContext& ctx) {
385 IPC::RequestParser rp{ctx}; 386 IPC::RequestParser rp{ctx};
386 const auto applet_resource_user_id{rp.Pop<u64>()}; 387 const auto applet_resource_user_id{rp.Pop<u64>()};
387 388
@@ -396,7 +397,7 @@ void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) {
396 rb.PushIpcInterface<IAppletResource>(applet_resource); 397 rb.PushIpcInterface<IAppletResource>(applet_resource);
397} 398}
398 399
399void Hid::ActivateDebugPad(Kernel::HLERequestContext& ctx) { 400void Hid::ActivateDebugPad(HLERequestContext& ctx) {
400 IPC::RequestParser rp{ctx}; 401 IPC::RequestParser rp{ctx};
401 const auto applet_resource_user_id{rp.Pop<u64>()}; 402 const auto applet_resource_user_id{rp.Pop<u64>()};
402 403
@@ -408,7 +409,7 @@ void Hid::ActivateDebugPad(Kernel::HLERequestContext& ctx) {
408 rb.Push(ResultSuccess); 409 rb.Push(ResultSuccess);
409} 410}
410 411
411void Hid::ActivateTouchScreen(Kernel::HLERequestContext& ctx) { 412void Hid::ActivateTouchScreen(HLERequestContext& ctx) {
412 IPC::RequestParser rp{ctx}; 413 IPC::RequestParser rp{ctx};
413 const auto applet_resource_user_id{rp.Pop<u64>()}; 414 const auto applet_resource_user_id{rp.Pop<u64>()};
414 415
@@ -420,7 +421,7 @@ void Hid::ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
420 rb.Push(ResultSuccess); 421 rb.Push(ResultSuccess);
421} 422}
422 423
423void Hid::ActivateMouse(Kernel::HLERequestContext& ctx) { 424void Hid::ActivateMouse(HLERequestContext& ctx) {
424 IPC::RequestParser rp{ctx}; 425 IPC::RequestParser rp{ctx};
425 const auto applet_resource_user_id{rp.Pop<u64>()}; 426 const auto applet_resource_user_id{rp.Pop<u64>()};
426 427
@@ -432,7 +433,7 @@ void Hid::ActivateMouse(Kernel::HLERequestContext& ctx) {
432 rb.Push(ResultSuccess); 433 rb.Push(ResultSuccess);
433} 434}
434 435
435void Hid::ActivateKeyboard(Kernel::HLERequestContext& ctx) { 436void Hid::ActivateKeyboard(HLERequestContext& ctx) {
436 IPC::RequestParser rp{ctx}; 437 IPC::RequestParser rp{ctx};
437 const auto applet_resource_user_id{rp.Pop<u64>()}; 438 const auto applet_resource_user_id{rp.Pop<u64>()};
438 439
@@ -444,7 +445,7 @@ void Hid::ActivateKeyboard(Kernel::HLERequestContext& ctx) {
444 rb.Push(ResultSuccess); 445 rb.Push(ResultSuccess);
445} 446}
446 447
447void Hid::SendKeyboardLockKeyEvent(Kernel::HLERequestContext& ctx) { 448void Hid::SendKeyboardLockKeyEvent(HLERequestContext& ctx) {
448 IPC::RequestParser rp{ctx}; 449 IPC::RequestParser rp{ctx};
449 const auto flags{rp.Pop<u32>()}; 450 const auto flags{rp.Pop<u32>()};
450 451
@@ -454,7 +455,7 @@ void Hid::SendKeyboardLockKeyEvent(Kernel::HLERequestContext& ctx) {
454 rb.Push(ResultSuccess); 455 rb.Push(ResultSuccess);
455} 456}
456 457
457void Hid::ActivateXpad(Kernel::HLERequestContext& ctx) { 458void Hid::ActivateXpad(HLERequestContext& ctx) {
458 IPC::RequestParser rp{ctx}; 459 IPC::RequestParser rp{ctx};
459 struct Parameters { 460 struct Parameters {
460 u32 basic_xpad_id; 461 u32 basic_xpad_id;
@@ -474,7 +475,7 @@ void Hid::ActivateXpad(Kernel::HLERequestContext& ctx) {
474 rb.Push(ResultSuccess); 475 rb.Push(ResultSuccess);
475} 476}
476 477
477void Hid::GetXpadIDs(Kernel::HLERequestContext& ctx) { 478void Hid::GetXpadIDs(HLERequestContext& ctx) {
478 IPC::RequestParser rp{ctx}; 479 IPC::RequestParser rp{ctx};
479 const auto applet_resource_user_id{rp.Pop<u64>()}; 480 const auto applet_resource_user_id{rp.Pop<u64>()};
480 481
@@ -485,7 +486,7 @@ void Hid::GetXpadIDs(Kernel::HLERequestContext& ctx) {
485 rb.Push(0); 486 rb.Push(0);
486} 487}
487 488
488void Hid::ActivateSixAxisSensor(Kernel::HLERequestContext& ctx) { 489void Hid::ActivateSixAxisSensor(HLERequestContext& ctx) {
489 IPC::RequestParser rp{ctx}; 490 IPC::RequestParser rp{ctx};
490 struct Parameters { 491 struct Parameters {
491 u32 basic_xpad_id; 492 u32 basic_xpad_id;
@@ -505,7 +506,7 @@ void Hid::ActivateSixAxisSensor(Kernel::HLERequestContext& ctx) {
505 rb.Push(ResultSuccess); 506 rb.Push(ResultSuccess);
506} 507}
507 508
508void Hid::DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx) { 509void Hid::DeactivateSixAxisSensor(HLERequestContext& ctx) {
509 IPC::RequestParser rp{ctx}; 510 IPC::RequestParser rp{ctx};
510 struct Parameters { 511 struct Parameters {
511 u32 basic_xpad_id; 512 u32 basic_xpad_id;
@@ -525,7 +526,7 @@ void Hid::DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx) {
525 rb.Push(ResultSuccess); 526 rb.Push(ResultSuccess);
526} 527}
527 528
528void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) { 529void Hid::StartSixAxisSensor(HLERequestContext& ctx) {
529 IPC::RequestParser rp{ctx}; 530 IPC::RequestParser rp{ctx};
530 struct Parameters { 531 struct Parameters {
531 Core::HID::SixAxisSensorHandle sixaxis_handle; 532 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -548,7 +549,7 @@ void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
548 rb.Push(result); 549 rb.Push(result);
549} 550}
550 551
551void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) { 552void Hid::StopSixAxisSensor(HLERequestContext& ctx) {
552 IPC::RequestParser rp{ctx}; 553 IPC::RequestParser rp{ctx};
553 struct Parameters { 554 struct Parameters {
554 Core::HID::SixAxisSensorHandle sixaxis_handle; 555 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -571,7 +572,7 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
571 rb.Push(result); 572 rb.Push(result);
572} 573}
573 574
574void Hid::IsSixAxisSensorFusionEnabled(Kernel::HLERequestContext& ctx) { 575void Hid::IsSixAxisSensorFusionEnabled(HLERequestContext& ctx) {
575 IPC::RequestParser rp{ctx}; 576 IPC::RequestParser rp{ctx};
576 struct Parameters { 577 struct Parameters {
577 Core::HID::SixAxisSensorHandle sixaxis_handle; 578 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -597,7 +598,7 @@ void Hid::IsSixAxisSensorFusionEnabled(Kernel::HLERequestContext& ctx) {
597 rb.Push(is_enabled); 598 rb.Push(is_enabled);
598} 599}
599 600
600void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) { 601void Hid::EnableSixAxisSensorFusion(HLERequestContext& ctx) {
601 IPC::RequestParser rp{ctx}; 602 IPC::RequestParser rp{ctx};
602 struct Parameters { 603 struct Parameters {
603 bool enable_sixaxis_sensor_fusion; 604 bool enable_sixaxis_sensor_fusion;
@@ -624,7 +625,7 @@ void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
624 rb.Push(result); 625 rb.Push(result);
625} 626}
626 627
627void Hid::SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) { 628void Hid::SetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
628 IPC::RequestParser rp{ctx}; 629 IPC::RequestParser rp{ctx};
629 struct Parameters { 630 struct Parameters {
630 Core::HID::SixAxisSensorHandle sixaxis_handle; 631 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -651,7 +652,7 @@ void Hid::SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
651 rb.Push(result); 652 rb.Push(result);
652} 653}
653 654
654void Hid::GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) { 655void Hid::GetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
655 IPC::RequestParser rp{ctx}; 656 IPC::RequestParser rp{ctx};
656 struct Parameters { 657 struct Parameters {
657 Core::HID::SixAxisSensorHandle sixaxis_handle; 658 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -678,7 +679,7 @@ void Hid::GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
678 rb.PushRaw(fusion_parameters); 679 rb.PushRaw(fusion_parameters);
679} 680}
680 681
681void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) { 682void Hid::ResetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
682 IPC::RequestParser rp{ctx}; 683 IPC::RequestParser rp{ctx};
683 struct Parameters { 684 struct Parameters {
684 Core::HID::SixAxisSensorHandle sixaxis_handle; 685 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -712,7 +713,7 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
712 rb.Push(result2); 713 rb.Push(result2);
713} 714}
714 715
715void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { 716void Hid::SetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
716 IPC::RequestParser rp{ctx}; 717 IPC::RequestParser rp{ctx};
717 const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()}; 718 const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()};
718 const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()}; 719 const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()};
@@ -731,7 +732,7 @@ void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
731 rb.Push(result); 732 rb.Push(result);
732} 733}
733 734
734void Hid::GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { 735void Hid::GetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
735 IPC::RequestParser rp{ctx}; 736 IPC::RequestParser rp{ctx};
736 struct Parameters { 737 struct Parameters {
737 Core::HID::SixAxisSensorHandle sixaxis_handle; 738 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -756,7 +757,7 @@ void Hid::GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
756 rb.PushEnum(drift_mode); 757 rb.PushEnum(drift_mode);
757} 758}
758 759
759void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { 760void Hid::ResetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
760 IPC::RequestParser rp{ctx}; 761 IPC::RequestParser rp{ctx};
761 struct Parameters { 762 struct Parameters {
762 Core::HID::SixAxisSensorHandle sixaxis_handle; 763 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -780,7 +781,7 @@ void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
780 rb.Push(result); 781 rb.Push(result);
781} 782}
782 783
783void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) { 784void Hid::IsSixAxisSensorAtRest(HLERequestContext& ctx) {
784 IPC::RequestParser rp{ctx}; 785 IPC::RequestParser rp{ctx};
785 struct Parameters { 786 struct Parameters {
786 Core::HID::SixAxisSensorHandle sixaxis_handle; 787 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -805,7 +806,7 @@ void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
805 rb.Push(is_at_rest); 806 rb.Push(is_at_rest);
806} 807}
807 808
808void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& ctx) { 809void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx) {
809 IPC::RequestParser rp{ctx}; 810 IPC::RequestParser rp{ctx};
810 struct Parameters { 811 struct Parameters {
811 Core::HID::SixAxisSensorHandle sixaxis_handle; 812 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -832,7 +833,7 @@ void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& c
832 rb.Push(is_firmware_available); 833 rb.Push(is_firmware_available);
833} 834}
834 835
835void Hid::EnableSixAxisSensorUnalteredPassthrough(Kernel::HLERequestContext& ctx) { 836void Hid::EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx) {
836 IPC::RequestParser rp{ctx}; 837 IPC::RequestParser rp{ctx};
837 struct Parameters { 838 struct Parameters {
838 bool enabled; 839 bool enabled;
@@ -858,7 +859,7 @@ void Hid::EnableSixAxisSensorUnalteredPassthrough(Kernel::HLERequestContext& ctx
858 rb.Push(result); 859 rb.Push(result);
859} 860}
860 861
861void Hid::IsSixAxisSensorUnalteredPassthroughEnabled(Kernel::HLERequestContext& ctx) { 862void Hid::IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx) {
862 IPC::RequestParser rp{ctx}; 863 IPC::RequestParser rp{ctx};
863 struct Parameters { 864 struct Parameters {
864 Core::HID::SixAxisSensorHandle sixaxis_handle; 865 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -885,7 +886,7 @@ void Hid::IsSixAxisSensorUnalteredPassthroughEnabled(Kernel::HLERequestContext&
885 rb.Push(is_unaltered_sisxaxis_enabled); 886 rb.Push(is_unaltered_sisxaxis_enabled);
886} 887}
887 888
888void Hid::LoadSixAxisSensorCalibrationParameter(Kernel::HLERequestContext& ctx) { 889void Hid::LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx) {
889 IPC::RequestParser rp{ctx}; 890 IPC::RequestParser rp{ctx};
890 struct Parameters { 891 struct Parameters {
891 Core::HID::SixAxisSensorHandle sixaxis_handle; 892 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -915,7 +916,7 @@ void Hid::LoadSixAxisSensorCalibrationParameter(Kernel::HLERequestContext& ctx)
915 rb.Push(result); 916 rb.Push(result);
916} 917}
917 918
918void Hid::GetSixAxisSensorIcInformation(Kernel::HLERequestContext& ctx) { 919void Hid::GetSixAxisSensorIcInformation(HLERequestContext& ctx) {
919 IPC::RequestParser rp{ctx}; 920 IPC::RequestParser rp{ctx};
920 struct Parameters { 921 struct Parameters {
921 Core::HID::SixAxisSensorHandle sixaxis_handle; 922 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -945,7 +946,7 @@ void Hid::GetSixAxisSensorIcInformation(Kernel::HLERequestContext& ctx) {
945 rb.Push(result); 946 rb.Push(result);
946} 947}
947 948
948void Hid::ResetIsSixAxisSensorDeviceNewlyAssigned(Kernel::HLERequestContext& ctx) { 949void Hid::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx) {
949 IPC::RequestParser rp{ctx}; 950 IPC::RequestParser rp{ctx};
950 struct Parameters { 951 struct Parameters {
951 Core::HID::SixAxisSensorHandle sixaxis_handle; 952 Core::HID::SixAxisSensorHandle sixaxis_handle;
@@ -970,7 +971,7 @@ void Hid::ResetIsSixAxisSensorDeviceNewlyAssigned(Kernel::HLERequestContext& ctx
970 rb.Push(result); 971 rb.Push(result);
971} 972}
972 973
973void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) { 974void Hid::ActivateGesture(HLERequestContext& ctx) {
974 IPC::RequestParser rp{ctx}; 975 IPC::RequestParser rp{ctx};
975 struct Parameters { 976 struct Parameters {
976 u32 unknown; 977 u32 unknown;
@@ -990,7 +991,7 @@ void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) {
990 rb.Push(ResultSuccess); 991 rb.Push(ResultSuccess);
991} 992}
992 993
993void Hid::SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { 994void Hid::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
994 IPC::RequestParser rp{ctx}; 995 IPC::RequestParser rp{ctx};
995 struct Parameters { 996 struct Parameters {
996 Core::HID::NpadStyleSet supported_styleset; 997 Core::HID::NpadStyleSet supported_styleset;
@@ -1011,7 +1012,7 @@ void Hid::SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
1011 rb.Push(ResultSuccess); 1012 rb.Push(ResultSuccess);
1012} 1013}
1013 1014
1014void Hid::GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { 1015void Hid::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
1015 IPC::RequestParser rp{ctx}; 1016 IPC::RequestParser rp{ctx};
1016 const auto applet_resource_user_id{rp.Pop<u64>()}; 1017 const auto applet_resource_user_id{rp.Pop<u64>()};
1017 1018
@@ -1024,7 +1025,7 @@ void Hid::GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
1024 .raw); 1025 .raw);
1025} 1026}
1026 1027
1027void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) { 1028void Hid::SetSupportedNpadIdType(HLERequestContext& ctx) {
1028 IPC::RequestParser rp{ctx}; 1029 IPC::RequestParser rp{ctx};
1029 const auto applet_resource_user_id{rp.Pop<u64>()}; 1030 const auto applet_resource_user_id{rp.Pop<u64>()};
1030 1031
@@ -1037,7 +1038,7 @@ void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
1037 rb.Push(result); 1038 rb.Push(result);
1038} 1039}
1039 1040
1040void Hid::ActivateNpad(Kernel::HLERequestContext& ctx) { 1041void Hid::ActivateNpad(HLERequestContext& ctx) {
1041 IPC::RequestParser rp{ctx}; 1042 IPC::RequestParser rp{ctx};
1042 const auto applet_resource_user_id{rp.Pop<u64>()}; 1043 const auto applet_resource_user_id{rp.Pop<u64>()};
1043 1044
@@ -1049,7 +1050,7 @@ void Hid::ActivateNpad(Kernel::HLERequestContext& ctx) {
1049 rb.Push(ResultSuccess); 1050 rb.Push(ResultSuccess);
1050} 1051}
1051 1052
1052void Hid::DeactivateNpad(Kernel::HLERequestContext& ctx) { 1053void Hid::DeactivateNpad(HLERequestContext& ctx) {
1053 IPC::RequestParser rp{ctx}; 1054 IPC::RequestParser rp{ctx};
1054 const auto applet_resource_user_id{rp.Pop<u64>()}; 1055 const auto applet_resource_user_id{rp.Pop<u64>()};
1055 1056
@@ -1061,7 +1062,7 @@ void Hid::DeactivateNpad(Kernel::HLERequestContext& ctx) {
1061 rb.Push(ResultSuccess); 1062 rb.Push(ResultSuccess);
1062} 1063}
1063 1064
1064void Hid::AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) { 1065void Hid::AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx) {
1065 IPC::RequestParser rp{ctx}; 1066 IPC::RequestParser rp{ctx};
1066 struct Parameters { 1067 struct Parameters {
1067 Core::HID::NpadIdType npad_id; 1068 Core::HID::NpadIdType npad_id;
@@ -1086,7 +1087,7 @@ void Hid::AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
1086 .GetStyleSetChangedEvent(parameters.npad_id)); 1087 .GetStyleSetChangedEvent(parameters.npad_id));
1087} 1088}
1088 1089
1089void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) { 1090void Hid::DisconnectNpad(HLERequestContext& ctx) {
1090 IPC::RequestParser rp{ctx}; 1091 IPC::RequestParser rp{ctx};
1091 struct Parameters { 1092 struct Parameters {
1092 Core::HID::NpadIdType npad_id; 1093 Core::HID::NpadIdType npad_id;
@@ -1107,7 +1108,7 @@ void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) {
1107 rb.Push(ResultSuccess); 1108 rb.Push(ResultSuccess);
1108} 1109}
1109 1110
1110void Hid::GetPlayerLedPattern(Kernel::HLERequestContext& ctx) { 1111void Hid::GetPlayerLedPattern(HLERequestContext& ctx) {
1111 IPC::RequestParser rp{ctx}; 1112 IPC::RequestParser rp{ctx};
1112 const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()}; 1113 const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
1113 1114
@@ -1122,7 +1123,7 @@ void Hid::GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
1122 rb.Push(pattern.raw); 1123 rb.Push(pattern.raw);
1123} 1124}
1124 1125
1125void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) { 1126void Hid::ActivateNpadWithRevision(HLERequestContext& ctx) {
1126 // Should have no effect with how our npad sets up the data 1127 // Should have no effect with how our npad sets up the data
1127 IPC::RequestParser rp{ctx}; 1128 IPC::RequestParser rp{ctx};
1128 struct Parameters { 1129 struct Parameters {
@@ -1143,7 +1144,7 @@ void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) {
1143 rb.Push(ResultSuccess); 1144 rb.Push(ResultSuccess);
1144} 1145}
1145 1146
1146void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { 1147void Hid::SetNpadJoyHoldType(HLERequestContext& ctx) {
1147 IPC::RequestParser rp{ctx}; 1148 IPC::RequestParser rp{ctx};
1148 const auto applet_resource_user_id{rp.Pop<u64>()}; 1149 const auto applet_resource_user_id{rp.Pop<u64>()};
1149 const auto hold_type{rp.PopEnum<Controller_NPad::NpadJoyHoldType>()}; 1150 const auto hold_type{rp.PopEnum<Controller_NPad::NpadJoyHoldType>()};
@@ -1157,7 +1158,7 @@ void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
1157 rb.Push(ResultSuccess); 1158 rb.Push(ResultSuccess);
1158} 1159}
1159 1160
1160void Hid::GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { 1161void Hid::GetNpadJoyHoldType(HLERequestContext& ctx) {
1161 IPC::RequestParser rp{ctx}; 1162 IPC::RequestParser rp{ctx};
1162 const auto applet_resource_user_id{rp.Pop<u64>()}; 1163 const auto applet_resource_user_id{rp.Pop<u64>()};
1163 1164
@@ -1168,7 +1169,7 @@ void Hid::GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
1168 rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad).GetHoldType()); 1169 rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad).GetHoldType());
1169} 1170}
1170 1171
1171void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) { 1172void Hid::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) {
1172 IPC::RequestParser rp{ctx}; 1173 IPC::RequestParser rp{ctx};
1173 struct Parameters { 1174 struct Parameters {
1174 Core::HID::NpadIdType npad_id; 1175 Core::HID::NpadIdType npad_id;
@@ -1190,7 +1191,7 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx
1190 rb.Push(ResultSuccess); 1191 rb.Push(ResultSuccess);
1191} 1192}
1192 1193
1193void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) { 1194void Hid::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
1194 IPC::RequestParser rp{ctx}; 1195 IPC::RequestParser rp{ctx};
1195 struct Parameters { 1196 struct Parameters {
1196 Core::HID::NpadIdType npad_id; 1197 Core::HID::NpadIdType npad_id;
@@ -1214,7 +1215,7 @@ void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) {
1214 rb.Push(ResultSuccess); 1215 rb.Push(ResultSuccess);
1215} 1216}
1216 1217
1217void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { 1218void Hid::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
1218 IPC::RequestParser rp{ctx}; 1219 IPC::RequestParser rp{ctx};
1219 struct Parameters { 1220 struct Parameters {
1220 Core::HID::NpadIdType npad_id; 1221 Core::HID::NpadIdType npad_id;
@@ -1235,7 +1236,7 @@ void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
1235 rb.Push(ResultSuccess); 1236 rb.Push(ResultSuccess);
1236} 1237}
1237 1238
1238void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { 1239void Hid::MergeSingleJoyAsDualJoy(HLERequestContext& ctx) {
1239 IPC::RequestParser rp{ctx}; 1240 IPC::RequestParser rp{ctx};
1240 const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()}; 1241 const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()};
1241 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; 1242 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
@@ -1251,7 +1252,7 @@ void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
1251 rb.Push(result); 1252 rb.Push(result);
1252} 1253}
1253 1254
1254void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { 1255void Hid::StartLrAssignmentMode(HLERequestContext& ctx) {
1255 IPC::RequestParser rp{ctx}; 1256 IPC::RequestParser rp{ctx};
1256 const auto applet_resource_user_id{rp.Pop<u64>()}; 1257 const auto applet_resource_user_id{rp.Pop<u64>()};
1257 1258
@@ -1263,7 +1264,7 @@ void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
1263 rb.Push(ResultSuccess); 1264 rb.Push(ResultSuccess);
1264} 1265}
1265 1266
1266void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) { 1267void Hid::StopLrAssignmentMode(HLERequestContext& ctx) {
1267 IPC::RequestParser rp{ctx}; 1268 IPC::RequestParser rp{ctx};
1268 const auto applet_resource_user_id{rp.Pop<u64>()}; 1269 const auto applet_resource_user_id{rp.Pop<u64>()};
1269 1270
@@ -1275,7 +1276,7 @@ void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
1275 rb.Push(ResultSuccess); 1276 rb.Push(ResultSuccess);
1276} 1277}
1277 1278
1278void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { 1279void Hid::SetNpadHandheldActivationMode(HLERequestContext& ctx) {
1279 IPC::RequestParser rp{ctx}; 1280 IPC::RequestParser rp{ctx};
1280 const auto applet_resource_user_id{rp.Pop<u64>()}; 1281 const auto applet_resource_user_id{rp.Pop<u64>()};
1281 const auto activation_mode{rp.PopEnum<Controller_NPad::NpadHandheldActivationMode>()}; 1282 const auto activation_mode{rp.PopEnum<Controller_NPad::NpadHandheldActivationMode>()};
@@ -1290,7 +1291,7 @@ void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
1290 rb.Push(ResultSuccess); 1291 rb.Push(ResultSuccess);
1291} 1292}
1292 1293
1293void Hid::GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { 1294void Hid::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
1294 IPC::RequestParser rp{ctx}; 1295 IPC::RequestParser rp{ctx};
1295 const auto applet_resource_user_id{rp.Pop<u64>()}; 1296 const auto applet_resource_user_id{rp.Pop<u64>()};
1296 1297
@@ -1302,7 +1303,7 @@ void Hid::GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
1302 .GetNpadHandheldActivationMode()); 1303 .GetNpadHandheldActivationMode());
1303} 1304}
1304 1305
1305void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) { 1306void Hid::SwapNpadAssignment(HLERequestContext& ctx) {
1306 IPC::RequestParser rp{ctx}; 1307 IPC::RequestParser rp{ctx};
1307 const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()}; 1308 const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()};
1308 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; 1309 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
@@ -1318,7 +1319,7 @@ void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
1318 rb.Push(result); 1319 rb.Push(result);
1319} 1320}
1320 1321
1321void Hid::IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx) { 1322void Hid::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx) {
1322 IPC::RequestParser rp{ctx}; 1323 IPC::RequestParser rp{ctx};
1323 struct Parameters { 1324 struct Parameters {
1324 Core::HID::NpadIdType npad_id; 1325 Core::HID::NpadIdType npad_id;
@@ -1342,7 +1343,7 @@ void Hid::IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext
1342 rb.Push(is_enabled); 1343 rb.Push(is_enabled);
1343} 1344}
1344 1345
1345void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx) { 1346void Hid::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) {
1346 IPC::RequestParser rp{ctx}; 1347 IPC::RequestParser rp{ctx};
1347 struct Parameters { 1348 struct Parameters {
1348 bool unintended_home_button_input_protection; 1349 bool unintended_home_button_input_protection;
@@ -1368,7 +1369,7 @@ void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& c
1368 rb.Push(result); 1369 rb.Push(result);
1369} 1370}
1370 1371
1371void Hid::SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx) { 1372void Hid::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
1372 IPC::RequestParser rp{ctx}; 1373 IPC::RequestParser rp{ctx};
1373 struct Parameters { 1374 struct Parameters {
1374 bool analog_stick_use_center_clamp; 1375 bool analog_stick_use_center_clamp;
@@ -1391,7 +1392,7 @@ void Hid::SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx) {
1391 rb.Push(ResultSuccess); 1392 rb.Push(ResultSuccess);
1392} 1393}
1393 1394
1394void Hid::SetNpadCaptureButtonAssignment(Kernel::HLERequestContext& ctx) { 1395void Hid::SetNpadCaptureButtonAssignment(HLERequestContext& ctx) {
1395 IPC::RequestParser rp{ctx}; 1396 IPC::RequestParser rp{ctx};
1396 struct Parameters { 1397 struct Parameters {
1397 Core::HID::NpadStyleSet npad_styleset; 1398 Core::HID::NpadStyleSet npad_styleset;
@@ -1411,7 +1412,7 @@ void Hid::SetNpadCaptureButtonAssignment(Kernel::HLERequestContext& ctx) {
1411 rb.Push(ResultSuccess); 1412 rb.Push(ResultSuccess);
1412} 1413}
1413 1414
1414void Hid::ClearNpadCaptureButtonAssignment(Kernel::HLERequestContext& ctx) { 1415void Hid::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) {
1415 IPC::RequestParser rp{ctx}; 1416 IPC::RequestParser rp{ctx};
1416 const auto applet_resource_user_id{rp.Pop<u64>()}; 1417 const auto applet_resource_user_id{rp.Pop<u64>()};
1417 1418
@@ -1422,7 +1423,7 @@ void Hid::ClearNpadCaptureButtonAssignment(Kernel::HLERequestContext& ctx) {
1422 rb.Push(ResultSuccess); 1423 rb.Push(ResultSuccess);
1423} 1424}
1424 1425
1425void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { 1426void Hid::GetVibrationDeviceInfo(HLERequestContext& ctx) {
1426 IPC::RequestParser rp{ctx}; 1427 IPC::RequestParser rp{ctx};
1427 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; 1428 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
1428 const auto& controller = 1429 const auto& controller =
@@ -1482,7 +1483,7 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
1482 rb.PushRaw(vibration_device_info); 1483 rb.PushRaw(vibration_device_info);
1483} 1484}
1484 1485
1485void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) { 1486void Hid::SendVibrationValue(HLERequestContext& ctx) {
1486 IPC::RequestParser rp{ctx}; 1487 IPC::RequestParser rp{ctx};
1487 struct Parameters { 1488 struct Parameters {
1488 Core::HID::VibrationDeviceHandle vibration_device_handle; 1489 Core::HID::VibrationDeviceHandle vibration_device_handle;
@@ -1507,7 +1508,7 @@ void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) {
1507 rb.Push(ResultSuccess); 1508 rb.Push(ResultSuccess);
1508} 1509}
1509 1510
1510void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) { 1511void Hid::GetActualVibrationValue(HLERequestContext& ctx) {
1511 IPC::RequestParser rp{ctx}; 1512 IPC::RequestParser rp{ctx};
1512 struct Parameters { 1513 struct Parameters {
1513 Core::HID::VibrationDeviceHandle vibration_device_handle; 1514 Core::HID::VibrationDeviceHandle vibration_device_handle;
@@ -1530,7 +1531,7 @@ void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
1530 .GetLastVibration(parameters.vibration_device_handle)); 1531 .GetLastVibration(parameters.vibration_device_handle));
1531} 1532}
1532 1533
1533void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) { 1534void Hid::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {
1534 LOG_DEBUG(Service_HID, "called"); 1535 LOG_DEBUG(Service_HID, "called");
1535 1536
1536 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1537 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -1538,7 +1539,7 @@ void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
1538 rb.PushIpcInterface<IActiveVibrationDeviceList>(system, applet_resource); 1539 rb.PushIpcInterface<IActiveVibrationDeviceList>(system, applet_resource);
1539} 1540}
1540 1541
1541void Hid::PermitVibration(Kernel::HLERequestContext& ctx) { 1542void Hid::PermitVibration(HLERequestContext& ctx) {
1542 IPC::RequestParser rp{ctx}; 1543 IPC::RequestParser rp{ctx};
1543 const auto can_vibrate{rp.Pop<bool>()}; 1544 const auto can_vibrate{rp.Pop<bool>()};
1544 1545
@@ -1552,7 +1553,7 @@ void Hid::PermitVibration(Kernel::HLERequestContext& ctx) {
1552 rb.Push(ResultSuccess); 1553 rb.Push(ResultSuccess);
1553} 1554}
1554 1555
1555void Hid::IsVibrationPermitted(Kernel::HLERequestContext& ctx) { 1556void Hid::IsVibrationPermitted(HLERequestContext& ctx) {
1556 LOG_DEBUG(Service_HID, "called"); 1557 LOG_DEBUG(Service_HID, "called");
1557 1558
1558 // nnSDK checks if a float is greater than zero. We return the bool we stored earlier 1559 // nnSDK checks if a float is greater than zero. We return the bool we stored earlier
@@ -1563,7 +1564,7 @@ void Hid::IsVibrationPermitted(Kernel::HLERequestContext& ctx) {
1563 rb.Push(is_enabled); 1564 rb.Push(is_enabled);
1564} 1565}
1565 1566
1566void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) { 1567void Hid::SendVibrationValues(HLERequestContext& ctx) {
1567 IPC::RequestParser rp{ctx}; 1568 IPC::RequestParser rp{ctx};
1568 const auto applet_resource_user_id{rp.Pop<u64>()}; 1569 const auto applet_resource_user_id{rp.Pop<u64>()};
1569 1570
@@ -1587,7 +1588,7 @@ void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
1587 rb.Push(ResultSuccess); 1588 rb.Push(ResultSuccess);
1588} 1589}
1589 1590
1590void Hid::SendVibrationGcErmCommand(Kernel::HLERequestContext& ctx) { 1591void Hid::SendVibrationGcErmCommand(HLERequestContext& ctx) {
1591 IPC::RequestParser rp{ctx}; 1592 IPC::RequestParser rp{ctx};
1592 struct Parameters { 1593 struct Parameters {
1593 Core::HID::VibrationDeviceHandle vibration_device_handle; 1594 Core::HID::VibrationDeviceHandle vibration_device_handle;
@@ -1648,7 +1649,7 @@ void Hid::SendVibrationGcErmCommand(Kernel::HLERequestContext& ctx) {
1648 rb.Push(ResultSuccess); 1649 rb.Push(ResultSuccess);
1649} 1650}
1650 1651
1651void Hid::GetActualVibrationGcErmCommand(Kernel::HLERequestContext& ctx) { 1652void Hid::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {
1652 IPC::RequestParser rp{ctx}; 1653 IPC::RequestParser rp{ctx};
1653 struct Parameters { 1654 struct Parameters {
1654 Core::HID::VibrationDeviceHandle vibration_device_handle; 1655 Core::HID::VibrationDeviceHandle vibration_device_handle;
@@ -1690,7 +1691,7 @@ void Hid::GetActualVibrationGcErmCommand(Kernel::HLERequestContext& ctx) {
1690 rb.PushEnum(gc_erm_command); 1691 rb.PushEnum(gc_erm_command);
1691} 1692}
1692 1693
1693void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { 1694void Hid::BeginPermitVibrationSession(HLERequestContext& ctx) {
1694 IPC::RequestParser rp{ctx}; 1695 IPC::RequestParser rp{ctx};
1695 const auto applet_resource_user_id{rp.Pop<u64>()}; 1696 const auto applet_resource_user_id{rp.Pop<u64>()};
1696 1697
@@ -1703,7 +1704,7 @@ void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
1703 rb.Push(ResultSuccess); 1704 rb.Push(ResultSuccess);
1704} 1705}
1705 1706
1706void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) { 1707void Hid::EndPermitVibrationSession(HLERequestContext& ctx) {
1707 applet_resource->GetController<Controller_NPad>(HidController::NPad) 1708 applet_resource->GetController<Controller_NPad>(HidController::NPad)
1708 .SetPermitVibrationSession(false); 1709 .SetPermitVibrationSession(false);
1709 1710
@@ -1713,7 +1714,7 @@ void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
1713 rb.Push(ResultSuccess); 1714 rb.Push(ResultSuccess);
1714} 1715}
1715 1716
1716void Hid::IsVibrationDeviceMounted(Kernel::HLERequestContext& ctx) { 1717void Hid::IsVibrationDeviceMounted(HLERequestContext& ctx) {
1717 IPC::RequestParser rp{ctx}; 1718 IPC::RequestParser rp{ctx};
1718 struct Parameters { 1719 struct Parameters {
1719 Core::HID::VibrationDeviceHandle vibration_device_handle; 1720 Core::HID::VibrationDeviceHandle vibration_device_handle;
@@ -1736,7 +1737,7 @@ void Hid::IsVibrationDeviceMounted(Kernel::HLERequestContext& ctx) {
1736 .IsVibrationDeviceMounted(parameters.vibration_device_handle)); 1737 .IsVibrationDeviceMounted(parameters.vibration_device_handle));
1737} 1738}
1738 1739
1739void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { 1740void Hid::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {
1740 IPC::RequestParser rp{ctx}; 1741 IPC::RequestParser rp{ctx};
1741 const auto applet_resource_user_id{rp.Pop<u64>()}; 1742 const auto applet_resource_user_id{rp.Pop<u64>()};
1742 1743
@@ -1748,7 +1749,7 @@ void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
1748 rb.Push(ResultSuccess); 1749 rb.Push(ResultSuccess);
1749} 1750}
1750 1751
1751void Hid::StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { 1752void Hid::StartConsoleSixAxisSensor(HLERequestContext& ctx) {
1752 IPC::RequestParser rp{ctx}; 1753 IPC::RequestParser rp{ctx};
1753 struct Parameters { 1754 struct Parameters {
1754 Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle; 1755 Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle;
@@ -1768,7 +1769,7 @@ void Hid::StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
1768 rb.Push(ResultSuccess); 1769 rb.Push(ResultSuccess);
1769} 1770}
1770 1771
1771void Hid::StopConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { 1772void Hid::StopConsoleSixAxisSensor(HLERequestContext& ctx) {
1772 IPC::RequestParser rp{ctx}; 1773 IPC::RequestParser rp{ctx};
1773 struct Parameters { 1774 struct Parameters {
1774 Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle; 1775 Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle;
@@ -1788,7 +1789,7 @@ void Hid::StopConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
1788 rb.Push(ResultSuccess); 1789 rb.Push(ResultSuccess);
1789} 1790}
1790 1791
1791void Hid::ActivateSevenSixAxisSensor(Kernel::HLERequestContext& ctx) { 1792void Hid::ActivateSevenSixAxisSensor(HLERequestContext& ctx) {
1792 IPC::RequestParser rp{ctx}; 1793 IPC::RequestParser rp{ctx};
1793 const auto applet_resource_user_id{rp.Pop<u64>()}; 1794 const auto applet_resource_user_id{rp.Pop<u64>()};
1794 1795
@@ -1800,7 +1801,7 @@ void Hid::ActivateSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
1800 rb.Push(ResultSuccess); 1801 rb.Push(ResultSuccess);
1801} 1802}
1802 1803
1803void Hid::StartSevenSixAxisSensor(Kernel::HLERequestContext& ctx) { 1804void Hid::StartSevenSixAxisSensor(HLERequestContext& ctx) {
1804 IPC::RequestParser rp{ctx}; 1805 IPC::RequestParser rp{ctx};
1805 const auto applet_resource_user_id{rp.Pop<u64>()}; 1806 const auto applet_resource_user_id{rp.Pop<u64>()};
1806 1807
@@ -1811,7 +1812,7 @@ void Hid::StartSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
1811 rb.Push(ResultSuccess); 1812 rb.Push(ResultSuccess);
1812} 1813}
1813 1814
1814void Hid::StopSevenSixAxisSensor(Kernel::HLERequestContext& ctx) { 1815void Hid::StopSevenSixAxisSensor(HLERequestContext& ctx) {
1815 IPC::RequestParser rp{ctx}; 1816 IPC::RequestParser rp{ctx};
1816 const auto applet_resource_user_id{rp.Pop<u64>()}; 1817 const auto applet_resource_user_id{rp.Pop<u64>()};
1817 1818
@@ -1822,7 +1823,7 @@ void Hid::StopSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
1822 rb.Push(ResultSuccess); 1823 rb.Push(ResultSuccess);
1823} 1824}
1824 1825
1825void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) { 1826void Hid::InitializeSevenSixAxisSensor(HLERequestContext& ctx) {
1826 IPC::RequestParser rp{ctx}; 1827 IPC::RequestParser rp{ctx};
1827 const auto applet_resource_user_id{rp.Pop<u64>()}; 1828 const auto applet_resource_user_id{rp.Pop<u64>()};
1828 const auto t_mem_1_size{rp.Pop<u64>()}; 1829 const auto t_mem_1_size{rp.Pop<u64>()};
@@ -1861,7 +1862,7 @@ void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
1861 .ActivateController(); 1862 .ActivateController();
1862 1863
1863 applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor) 1864 applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
1864 .SetTransferMemoryPointer(system.Memory().GetPointer(t_mem_1->GetSourceAddress())); 1865 .SetTransferMemoryAddress(t_mem_1->GetSourceAddress());
1865 1866
1866 LOG_WARNING(Service_HID, 1867 LOG_WARNING(Service_HID,
1867 "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, " 1868 "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, "
@@ -1872,7 +1873,7 @@ void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
1872 rb.Push(ResultSuccess); 1873 rb.Push(ResultSuccess);
1873} 1874}
1874 1875
1875void Hid::FinalizeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) { 1876void Hid::FinalizeSevenSixAxisSensor(HLERequestContext& ctx) {
1876 IPC::RequestParser rp{ctx}; 1877 IPC::RequestParser rp{ctx};
1877 const auto applet_resource_user_id{rp.Pop<u64>()}; 1878 const auto applet_resource_user_id{rp.Pop<u64>()};
1878 1879
@@ -1883,7 +1884,7 @@ void Hid::FinalizeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
1883 rb.Push(ResultSuccess); 1884 rb.Push(ResultSuccess);
1884} 1885}
1885 1886
1886void Hid::ResetSevenSixAxisSensorTimestamp(Kernel::HLERequestContext& ctx) { 1887void Hid::ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx) {
1887 IPC::RequestParser rp{ctx}; 1888 IPC::RequestParser rp{ctx};
1888 const auto applet_resource_user_id{rp.Pop<u64>()}; 1889 const auto applet_resource_user_id{rp.Pop<u64>()};
1889 1890
@@ -1896,7 +1897,7 @@ void Hid::ResetSevenSixAxisSensorTimestamp(Kernel::HLERequestContext& ctx) {
1896 rb.Push(ResultSuccess); 1897 rb.Push(ResultSuccess);
1897} 1898}
1898 1899
1899void Hid::IsUsbFullKeyControllerEnabled(Kernel::HLERequestContext& ctx) { 1900void Hid::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
1900 IPC::RequestParser rp{ctx}; 1901 IPC::RequestParser rp{ctx};
1901 1902
1902 LOG_WARNING(Service_HID, "(STUBBED) called"); 1903 LOG_WARNING(Service_HID, "(STUBBED) called");
@@ -1906,7 +1907,7 @@ void Hid::IsUsbFullKeyControllerEnabled(Kernel::HLERequestContext& ctx) {
1906 rb.Push(false); 1907 rb.Push(false);
1907} 1908}
1908 1909
1909void Hid::GetPalmaConnectionHandle(Kernel::HLERequestContext& ctx) { 1910void Hid::GetPalmaConnectionHandle(HLERequestContext& ctx) {
1910 IPC::RequestParser rp{ctx}; 1911 IPC::RequestParser rp{ctx};
1911 struct Parameters { 1912 struct Parameters {
1912 Core::HID::NpadIdType npad_id; 1913 Core::HID::NpadIdType npad_id;
@@ -1929,7 +1930,7 @@ void Hid::GetPalmaConnectionHandle(Kernel::HLERequestContext& ctx) {
1929 rb.PushRaw(handle); 1930 rb.PushRaw(handle);
1930} 1931}
1931 1932
1932void Hid::InitializePalma(Kernel::HLERequestContext& ctx) { 1933void Hid::InitializePalma(HLERequestContext& ctx) {
1933 IPC::RequestParser rp{ctx}; 1934 IPC::RequestParser rp{ctx};
1934 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 1935 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1935 1936
@@ -1942,7 +1943,7 @@ void Hid::InitializePalma(Kernel::HLERequestContext& ctx) {
1942 rb.Push(result); 1943 rb.Push(result);
1943} 1944}
1944 1945
1945void Hid::AcquirePalmaOperationCompleteEvent(Kernel::HLERequestContext& ctx) { 1946void Hid::AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx) {
1946 IPC::RequestParser rp{ctx}; 1947 IPC::RequestParser rp{ctx};
1947 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 1948 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1948 1949
@@ -1955,7 +1956,7 @@ void Hid::AcquirePalmaOperationCompleteEvent(Kernel::HLERequestContext& ctx) {
1955 rb.PushCopyObjects(controller.AcquirePalmaOperationCompleteEvent(connection_handle)); 1956 rb.PushCopyObjects(controller.AcquirePalmaOperationCompleteEvent(connection_handle));
1956} 1957}
1957 1958
1958void Hid::GetPalmaOperationInfo(Kernel::HLERequestContext& ctx) { 1959void Hid::GetPalmaOperationInfo(HLERequestContext& ctx) {
1959 IPC::RequestParser rp{ctx}; 1960 IPC::RequestParser rp{ctx};
1960 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 1961 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1961 1962
@@ -1977,7 +1978,7 @@ void Hid::GetPalmaOperationInfo(Kernel::HLERequestContext& ctx) {
1977 rb.Push(static_cast<u64>(operation_type)); 1978 rb.Push(static_cast<u64>(operation_type));
1978} 1979}
1979 1980
1980void Hid::PlayPalmaActivity(Kernel::HLERequestContext& ctx) { 1981void Hid::PlayPalmaActivity(HLERequestContext& ctx) {
1981 IPC::RequestParser rp{ctx}; 1982 IPC::RequestParser rp{ctx};
1982 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 1983 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1983 const auto palma_activity{rp.Pop<u64>()}; 1984 const auto palma_activity{rp.Pop<u64>()};
@@ -1992,7 +1993,7 @@ void Hid::PlayPalmaActivity(Kernel::HLERequestContext& ctx) {
1992 rb.Push(result); 1993 rb.Push(result);
1993} 1994}
1994 1995
1995void Hid::SetPalmaFrModeType(Kernel::HLERequestContext& ctx) { 1996void Hid::SetPalmaFrModeType(HLERequestContext& ctx) {
1996 IPC::RequestParser rp{ctx}; 1997 IPC::RequestParser rp{ctx};
1997 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 1998 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1998 const auto fr_mode{rp.PopEnum<Controller_Palma::PalmaFrModeType>()}; 1999 const auto fr_mode{rp.PopEnum<Controller_Palma::PalmaFrModeType>()};
@@ -2007,7 +2008,7 @@ void Hid::SetPalmaFrModeType(Kernel::HLERequestContext& ctx) {
2007 rb.Push(result); 2008 rb.Push(result);
2008} 2009}
2009 2010
2010void Hid::ReadPalmaStep(Kernel::HLERequestContext& ctx) { 2011void Hid::ReadPalmaStep(HLERequestContext& ctx) {
2011 IPC::RequestParser rp{ctx}; 2012 IPC::RequestParser rp{ctx};
2012 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2013 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2013 2014
@@ -2020,7 +2021,7 @@ void Hid::ReadPalmaStep(Kernel::HLERequestContext& ctx) {
2020 rb.Push(result); 2021 rb.Push(result);
2021} 2022}
2022 2023
2023void Hid::EnablePalmaStep(Kernel::HLERequestContext& ctx) { 2024void Hid::EnablePalmaStep(HLERequestContext& ctx) {
2024 IPC::RequestParser rp{ctx}; 2025 IPC::RequestParser rp{ctx};
2025 struct Parameters { 2026 struct Parameters {
2026 bool is_enabled; 2027 bool is_enabled;
@@ -2042,7 +2043,7 @@ void Hid::EnablePalmaStep(Kernel::HLERequestContext& ctx) {
2042 rb.Push(result); 2043 rb.Push(result);
2043} 2044}
2044 2045
2045void Hid::ResetPalmaStep(Kernel::HLERequestContext& ctx) { 2046void Hid::ResetPalmaStep(HLERequestContext& ctx) {
2046 IPC::RequestParser rp{ctx}; 2047 IPC::RequestParser rp{ctx};
2047 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2048 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2048 2049
@@ -2055,21 +2056,21 @@ void Hid::ResetPalmaStep(Kernel::HLERequestContext& ctx) {
2055 rb.Push(result); 2056 rb.Push(result);
2056} 2057}
2057 2058
2058void Hid::ReadPalmaApplicationSection(Kernel::HLERequestContext& ctx) { 2059void Hid::ReadPalmaApplicationSection(HLERequestContext& ctx) {
2059 LOG_WARNING(Service_HID, "(STUBBED) called"); 2060 LOG_WARNING(Service_HID, "(STUBBED) called");
2060 2061
2061 IPC::ResponseBuilder rb{ctx, 2}; 2062 IPC::ResponseBuilder rb{ctx, 2};
2062 rb.Push(ResultSuccess); 2063 rb.Push(ResultSuccess);
2063} 2064}
2064 2065
2065void Hid::WritePalmaApplicationSection(Kernel::HLERequestContext& ctx) { 2066void Hid::WritePalmaApplicationSection(HLERequestContext& ctx) {
2066 LOG_WARNING(Service_HID, "(STUBBED) called"); 2067 LOG_WARNING(Service_HID, "(STUBBED) called");
2067 2068
2068 IPC::ResponseBuilder rb{ctx, 2}; 2069 IPC::ResponseBuilder rb{ctx, 2};
2069 rb.Push(ResultSuccess); 2070 rb.Push(ResultSuccess);
2070} 2071}
2071 2072
2072void Hid::ReadPalmaUniqueCode(Kernel::HLERequestContext& ctx) { 2073void Hid::ReadPalmaUniqueCode(HLERequestContext& ctx) {
2073 IPC::RequestParser rp{ctx}; 2074 IPC::RequestParser rp{ctx};
2074 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2075 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2075 2076
@@ -2082,7 +2083,7 @@ void Hid::ReadPalmaUniqueCode(Kernel::HLERequestContext& ctx) {
2082 rb.Push(ResultSuccess); 2083 rb.Push(ResultSuccess);
2083} 2084}
2084 2085
2085void Hid::SetPalmaUniqueCodeInvalid(Kernel::HLERequestContext& ctx) { 2086void Hid::SetPalmaUniqueCodeInvalid(HLERequestContext& ctx) {
2086 IPC::RequestParser rp{ctx}; 2087 IPC::RequestParser rp{ctx};
2087 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2088 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2088 2089
@@ -2095,14 +2096,14 @@ void Hid::SetPalmaUniqueCodeInvalid(Kernel::HLERequestContext& ctx) {
2095 rb.Push(ResultSuccess); 2096 rb.Push(ResultSuccess);
2096} 2097}
2097 2098
2098void Hid::WritePalmaActivityEntry(Kernel::HLERequestContext& ctx) { 2099void Hid::WritePalmaActivityEntry(HLERequestContext& ctx) {
2099 LOG_CRITICAL(Service_HID, "(STUBBED) called"); 2100 LOG_CRITICAL(Service_HID, "(STUBBED) called");
2100 2101
2101 IPC::ResponseBuilder rb{ctx, 2}; 2102 IPC::ResponseBuilder rb{ctx, 2};
2102 rb.Push(ResultSuccess); 2103 rb.Push(ResultSuccess);
2103} 2104}
2104 2105
2105void Hid::WritePalmaRgbLedPatternEntry(Kernel::HLERequestContext& ctx) { 2106void Hid::WritePalmaRgbLedPatternEntry(HLERequestContext& ctx) {
2106 IPC::RequestParser rp{ctx}; 2107 IPC::RequestParser rp{ctx};
2107 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2108 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2108 const auto unknown{rp.Pop<u64>()}; 2109 const auto unknown{rp.Pop<u64>()};
@@ -2119,7 +2120,7 @@ void Hid::WritePalmaRgbLedPatternEntry(Kernel::HLERequestContext& ctx) {
2119 rb.Push(ResultSuccess); 2120 rb.Push(ResultSuccess);
2120} 2121}
2121 2122
2122void Hid::WritePalmaWaveEntry(Kernel::HLERequestContext& ctx) { 2123void Hid::WritePalmaWaveEntry(HLERequestContext& ctx) {
2123 IPC::RequestParser rp{ctx}; 2124 IPC::RequestParser rp{ctx};
2124 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2125 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2125 const auto wave_set{rp.PopEnum<Controller_Palma::PalmaWaveSet>()}; 2126 const auto wave_set{rp.PopEnum<Controller_Palma::PalmaWaveSet>()};
@@ -2148,14 +2149,13 @@ void Hid::WritePalmaWaveEntry(Kernel::HLERequestContext& ctx) {
2148 connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size); 2149 connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);
2149 2150
2150 applet_resource->GetController<Controller_Palma>(HidController::Palma) 2151 applet_resource->GetController<Controller_Palma>(HidController::Palma)
2151 .WritePalmaWaveEntry(connection_handle, wave_set, 2152 .WritePalmaWaveEntry(connection_handle, wave_set, t_mem->GetSourceAddress(), t_mem_size);
2152 system.Memory().GetPointer(t_mem->GetSourceAddress()), t_mem_size);
2153 2153
2154 IPC::ResponseBuilder rb{ctx, 2}; 2154 IPC::ResponseBuilder rb{ctx, 2};
2155 rb.Push(ResultSuccess); 2155 rb.Push(ResultSuccess);
2156} 2156}
2157 2157
2158void Hid::SetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx) { 2158void Hid::SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
2159 IPC::RequestParser rp{ctx}; 2159 IPC::RequestParser rp{ctx};
2160 struct Parameters { 2160 struct Parameters {
2161 s32 database_id_version; 2161 s32 database_id_version;
@@ -2177,7 +2177,7 @@ void Hid::SetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx)
2177 rb.Push(ResultSuccess); 2177 rb.Push(ResultSuccess);
2178} 2178}
2179 2179
2180void Hid::GetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx) { 2180void Hid::GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
2181 IPC::RequestParser rp{ctx}; 2181 IPC::RequestParser rp{ctx};
2182 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2182 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2183 2183
@@ -2190,14 +2190,14 @@ void Hid::GetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx)
2190 rb.Push(ResultSuccess); 2190 rb.Push(ResultSuccess);
2191} 2191}
2192 2192
2193void Hid::SuspendPalmaFeature(Kernel::HLERequestContext& ctx) { 2193void Hid::SuspendPalmaFeature(HLERequestContext& ctx) {
2194 LOG_WARNING(Service_HID, "(STUBBED) called"); 2194 LOG_WARNING(Service_HID, "(STUBBED) called");
2195 2195
2196 IPC::ResponseBuilder rb{ctx, 2}; 2196 IPC::ResponseBuilder rb{ctx, 2};
2197 rb.Push(ResultSuccess); 2197 rb.Push(ResultSuccess);
2198} 2198}
2199 2199
2200void Hid::GetPalmaOperationResult(Kernel::HLERequestContext& ctx) { 2200void Hid::GetPalmaOperationResult(HLERequestContext& ctx) {
2201 IPC::RequestParser rp{ctx}; 2201 IPC::RequestParser rp{ctx};
2202 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2202 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2203 2203
@@ -2210,21 +2210,21 @@ void Hid::GetPalmaOperationResult(Kernel::HLERequestContext& ctx) {
2210 rb.Push(result); 2210 rb.Push(result);
2211} 2211}
2212 2212
2213void Hid::ReadPalmaPlayLog(Kernel::HLERequestContext& ctx) { 2213void Hid::ReadPalmaPlayLog(HLERequestContext& ctx) {
2214 LOG_WARNING(Service_HID, "(STUBBED) called"); 2214 LOG_WARNING(Service_HID, "(STUBBED) called");
2215 2215
2216 IPC::ResponseBuilder rb{ctx, 2}; 2216 IPC::ResponseBuilder rb{ctx, 2};
2217 rb.Push(ResultSuccess); 2217 rb.Push(ResultSuccess);
2218} 2218}
2219 2219
2220void Hid::ResetPalmaPlayLog(Kernel::HLERequestContext& ctx) { 2220void Hid::ResetPalmaPlayLog(HLERequestContext& ctx) {
2221 LOG_WARNING(Service_HID, "(STUBBED) called"); 2221 LOG_WARNING(Service_HID, "(STUBBED) called");
2222 2222
2223 IPC::ResponseBuilder rb{ctx, 2}; 2223 IPC::ResponseBuilder rb{ctx, 2};
2224 rb.Push(ResultSuccess); 2224 rb.Push(ResultSuccess);
2225} 2225}
2226 2226
2227void Hid::SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) { 2227void Hid::SetIsPalmaAllConnectable(HLERequestContext& ctx) {
2228 IPC::RequestParser rp{ctx}; 2228 IPC::RequestParser rp{ctx};
2229 struct Parameters { 2229 struct Parameters {
2230 bool is_palma_all_connectable; 2230 bool is_palma_all_connectable;
@@ -2246,14 +2246,14 @@ void Hid::SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) {
2246 rb.Push(ResultSuccess); 2246 rb.Push(ResultSuccess);
2247} 2247}
2248 2248
2249void Hid::SetIsPalmaPairedConnectable(Kernel::HLERequestContext& ctx) { 2249void Hid::SetIsPalmaPairedConnectable(HLERequestContext& ctx) {
2250 LOG_WARNING(Service_HID, "(STUBBED) called"); 2250 LOG_WARNING(Service_HID, "(STUBBED) called");
2251 2251
2252 IPC::ResponseBuilder rb{ctx, 2}; 2252 IPC::ResponseBuilder rb{ctx, 2};
2253 rb.Push(ResultSuccess); 2253 rb.Push(ResultSuccess);
2254} 2254}
2255 2255
2256void Hid::PairPalma(Kernel::HLERequestContext& ctx) { 2256void Hid::PairPalma(HLERequestContext& ctx) {
2257 IPC::RequestParser rp{ctx}; 2257 IPC::RequestParser rp{ctx};
2258 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2258 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2259 2259
@@ -2266,7 +2266,7 @@ void Hid::PairPalma(Kernel::HLERequestContext& ctx) {
2266 rb.Push(ResultSuccess); 2266 rb.Push(ResultSuccess);
2267} 2267}
2268 2268
2269void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) { 2269void Hid::SetPalmaBoostMode(HLERequestContext& ctx) {
2270 IPC::RequestParser rp{ctx}; 2270 IPC::RequestParser rp{ctx};
2271 const auto palma_boost_mode{rp.Pop<bool>()}; 2271 const auto palma_boost_mode{rp.Pop<bool>()};
2272 2272
@@ -2279,35 +2279,35 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
2279 rb.Push(ResultSuccess); 2279 rb.Push(ResultSuccess);
2280} 2280}
2281 2281
2282void Hid::CancelWritePalmaWaveEntry(Kernel::HLERequestContext& ctx) { 2282void Hid::CancelWritePalmaWaveEntry(HLERequestContext& ctx) {
2283 LOG_WARNING(Service_HID, "(STUBBED) called"); 2283 LOG_WARNING(Service_HID, "(STUBBED) called");
2284 2284
2285 IPC::ResponseBuilder rb{ctx, 2}; 2285 IPC::ResponseBuilder rb{ctx, 2};
2286 rb.Push(ResultSuccess); 2286 rb.Push(ResultSuccess);
2287} 2287}
2288 2288
2289void Hid::EnablePalmaBoostMode(Kernel::HLERequestContext& ctx) { 2289void Hid::EnablePalmaBoostMode(HLERequestContext& ctx) {
2290 LOG_WARNING(Service_HID, "(STUBBED) called"); 2290 LOG_WARNING(Service_HID, "(STUBBED) called");
2291 2291
2292 IPC::ResponseBuilder rb{ctx, 2}; 2292 IPC::ResponseBuilder rb{ctx, 2};
2293 rb.Push(ResultSuccess); 2293 rb.Push(ResultSuccess);
2294} 2294}
2295 2295
2296void Hid::GetPalmaBluetoothAddress(Kernel::HLERequestContext& ctx) { 2296void Hid::GetPalmaBluetoothAddress(HLERequestContext& ctx) {
2297 LOG_WARNING(Service_HID, "(STUBBED) called"); 2297 LOG_WARNING(Service_HID, "(STUBBED) called");
2298 2298
2299 IPC::ResponseBuilder rb{ctx, 2}; 2299 IPC::ResponseBuilder rb{ctx, 2};
2300 rb.Push(ResultSuccess); 2300 rb.Push(ResultSuccess);
2301} 2301}
2302 2302
2303void Hid::SetDisallowedPalmaConnection(Kernel::HLERequestContext& ctx) { 2303void Hid::SetDisallowedPalmaConnection(HLERequestContext& ctx) {
2304 LOG_WARNING(Service_HID, "(STUBBED) called"); 2304 LOG_WARNING(Service_HID, "(STUBBED) called");
2305 2305
2306 IPC::ResponseBuilder rb{ctx, 2}; 2306 IPC::ResponseBuilder rb{ctx, 2};
2307 rb.Push(ResultSuccess); 2307 rb.Push(ResultSuccess);
2308} 2308}
2309 2309
2310void Hid::SetNpadCommunicationMode(Kernel::HLERequestContext& ctx) { 2310void Hid::SetNpadCommunicationMode(HLERequestContext& ctx) {
2311 IPC::RequestParser rp{ctx}; 2311 IPC::RequestParser rp{ctx};
2312 const auto applet_resource_user_id{rp.Pop<u64>()}; 2312 const auto applet_resource_user_id{rp.Pop<u64>()};
2313 const auto communication_mode{rp.PopEnum<Controller_NPad::NpadCommunicationMode>()}; 2313 const auto communication_mode{rp.PopEnum<Controller_NPad::NpadCommunicationMode>()};
@@ -2322,7 +2322,7 @@ void Hid::SetNpadCommunicationMode(Kernel::HLERequestContext& ctx) {
2322 rb.Push(ResultSuccess); 2322 rb.Push(ResultSuccess);
2323} 2323}
2324 2324
2325void Hid::GetNpadCommunicationMode(Kernel::HLERequestContext& ctx) { 2325void Hid::GetNpadCommunicationMode(HLERequestContext& ctx) {
2326 IPC::RequestParser rp{ctx}; 2326 IPC::RequestParser rp{ctx};
2327 2327
2328 LOG_WARNING(Service_HID, "(STUBBED) called"); 2328 LOG_WARNING(Service_HID, "(STUBBED) called");
@@ -2333,7 +2333,7 @@ void Hid::GetNpadCommunicationMode(Kernel::HLERequestContext& ctx) {
2333 .GetNpadCommunicationMode()); 2333 .GetNpadCommunicationMode());
2334} 2334}
2335 2335
2336void Hid::SetTouchScreenConfiguration(Kernel::HLERequestContext& ctx) { 2336void Hid::SetTouchScreenConfiguration(HLERequestContext& ctx) {
2337 IPC::RequestParser rp{ctx}; 2337 IPC::RequestParser rp{ctx};
2338 const auto touchscreen_mode{rp.PopRaw<Controller_Touchscreen::TouchScreenConfigurationForNx>()}; 2338 const auto touchscreen_mode{rp.PopRaw<Controller_Touchscreen::TouchScreenConfigurationForNx>()};
2339 const auto applet_resource_user_id{rp.Pop<u64>()}; 2339 const auto applet_resource_user_id{rp.Pop<u64>()};
@@ -2345,7 +2345,7 @@ void Hid::SetTouchScreenConfiguration(Kernel::HLERequestContext& ctx) {
2345 rb.Push(ResultSuccess); 2345 rb.Push(ResultSuccess);
2346} 2346}
2347 2347
2348void Hid::IsFirmwareUpdateNeededForNotification(Kernel::HLERequestContext& ctx) { 2348void Hid::IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx) {
2349 IPC::RequestParser rp{ctx}; 2349 IPC::RequestParser rp{ctx};
2350 struct Parameters { 2350 struct Parameters {
2351 s32 unknown; 2351 s32 unknown;
@@ -2719,7 +2719,7 @@ public:
2719 } 2719 }
2720 2720
2721private: 2721private:
2722 void ApplyNpadSystemCommonPolicy(Kernel::HLERequestContext& ctx) { 2722 void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
2723 // We already do this for homebrew so we can just stub it out 2723 // We already do this for homebrew so we can just stub it out
2724 LOG_WARNING(Service_HID, "called"); 2724 LOG_WARNING(Service_HID, "called");
2725 2725
@@ -2727,7 +2727,7 @@ private:
2727 rb.Push(ResultSuccess); 2727 rb.Push(ResultSuccess);
2728 } 2728 }
2729 2729
2730 void GetUniquePadsFromNpad(Kernel::HLERequestContext& ctx) { 2730 void GetUniquePadsFromNpad(HLERequestContext& ctx) {
2731 IPC::RequestParser rp{ctx}; 2731 IPC::RequestParser rp{ctx};
2732 const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()}; 2732 const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
2733 2733
@@ -2740,16 +2740,20 @@ private:
2740 } 2740 }
2741}; 2741};
2742 2742
2743void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 2743void LoopProcess(Core::System& system) {
2744 std::make_shared<Hid>(system)->InstallAsService(service_manager); 2744 auto server_manager = std::make_unique<ServerManager>(system);
2745 std::make_shared<HidBus>(system)->InstallAsService(service_manager);
2746 std::make_shared<HidDbg>(system)->InstallAsService(service_manager);
2747 std::make_shared<HidSys>(system)->InstallAsService(service_manager);
2748 2745
2749 std::make_shared<Service::IRS::IRS>(system)->InstallAsService(service_manager); 2746 server_manager->RegisterNamedService("hid", std::make_shared<Hid>(system));
2750 std::make_shared<Service::IRS::IRS_SYS>(system)->InstallAsService(service_manager); 2747 server_manager->RegisterNamedService("hidbus", std::make_shared<HidBus>(system));
2748 server_manager->RegisterNamedService("hid:dbg", std::make_shared<HidDbg>(system));
2749 server_manager->RegisterNamedService("hid:sys", std::make_shared<HidSys>(system));
2751 2750
2752 std::make_shared<XCD_SYS>(system)->InstallAsService(service_manager); 2751 server_manager->RegisterNamedService("irs", std::make_shared<Service::IRS::IRS>(system));
2752 server_manager->RegisterNamedService("irs:sys",
2753 std::make_shared<Service::IRS::IRS_SYS>(system));
2754
2755 server_manager->RegisterNamedService("xcd:sys", std::make_shared<XCD_SYS>(system));
2756 system.RunServer(std::move(server_manager));
2753} 2757}
2754 2758
2755} // namespace Service::HID 2759} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 8fc9ed88a..c69e5f3fb 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -61,16 +61,22 @@ public:
61private: 61private:
62 template <typename T> 62 template <typename T>
63 void MakeController(HidController controller, u8* shared_memory) { 63 void MakeController(HidController controller, u8* shared_memory) {
64 controllers[static_cast<std::size_t>(controller)] = 64 if constexpr (std::is_constructible_v<T, Core::System&, u8*>) {
65 std::make_unique<T>(system.HIDCore(), shared_memory); 65 controllers[static_cast<std::size_t>(controller)] =
66 std::make_unique<T>(system, shared_memory);
67 } else {
68 controllers[static_cast<std::size_t>(controller)] =
69 std::make_unique<T>(system.HIDCore(), shared_memory);
70 }
66 } 71 }
72
67 template <typename T> 73 template <typename T>
68 void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) { 74 void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) {
69 controllers[static_cast<std::size_t>(controller)] = 75 controllers[static_cast<std::size_t>(controller)] =
70 std::make_unique<T>(system.HIDCore(), shared_memory, service_context); 76 std::make_unique<T>(system.HIDCore(), shared_memory, service_context);
71 } 77 }
72 78
73 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); 79 void GetSharedMemoryHandle(HLERequestContext& ctx);
74 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 80 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
75 void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 81 void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
76 void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 82 void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
@@ -95,122 +101,121 @@ public:
95 std::shared_ptr<IAppletResource> GetAppletResource(); 101 std::shared_ptr<IAppletResource> GetAppletResource();
96 102
97private: 103private:
98 void CreateAppletResource(Kernel::HLERequestContext& ctx); 104 void CreateAppletResource(HLERequestContext& ctx);
99 void ActivateDebugPad(Kernel::HLERequestContext& ctx); 105 void ActivateDebugPad(HLERequestContext& ctx);
100 void ActivateTouchScreen(Kernel::HLERequestContext& ctx); 106 void ActivateTouchScreen(HLERequestContext& ctx);
101 void ActivateMouse(Kernel::HLERequestContext& ctx); 107 void ActivateMouse(HLERequestContext& ctx);
102 void ActivateKeyboard(Kernel::HLERequestContext& ctx); 108 void ActivateKeyboard(HLERequestContext& ctx);
103 void SendKeyboardLockKeyEvent(Kernel::HLERequestContext& ctx); 109 void SendKeyboardLockKeyEvent(HLERequestContext& ctx);
104 void ActivateXpad(Kernel::HLERequestContext& ctx); 110 void ActivateXpad(HLERequestContext& ctx);
105 void GetXpadIDs(Kernel::HLERequestContext& ctx); 111 void GetXpadIDs(HLERequestContext& ctx);
106 void ActivateSixAxisSensor(Kernel::HLERequestContext& ctx); 112 void ActivateSixAxisSensor(HLERequestContext& ctx);
107 void DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx); 113 void DeactivateSixAxisSensor(HLERequestContext& ctx);
108 void StartSixAxisSensor(Kernel::HLERequestContext& ctx); 114 void StartSixAxisSensor(HLERequestContext& ctx);
109 void StopSixAxisSensor(Kernel::HLERequestContext& ctx); 115 void StopSixAxisSensor(HLERequestContext& ctx);
110 void IsSixAxisSensorFusionEnabled(Kernel::HLERequestContext& ctx); 116 void IsSixAxisSensorFusionEnabled(HLERequestContext& ctx);
111 void EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx); 117 void EnableSixAxisSensorFusion(HLERequestContext& ctx);
112 void SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx); 118 void SetSixAxisSensorFusionParameters(HLERequestContext& ctx);
113 void GetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx); 119 void GetSixAxisSensorFusionParameters(HLERequestContext& ctx);
114 void ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx); 120 void ResetSixAxisSensorFusionParameters(HLERequestContext& ctx);
115 void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx); 121 void SetGyroscopeZeroDriftMode(HLERequestContext& ctx);
116 void GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx); 122 void GetGyroscopeZeroDriftMode(HLERequestContext& ctx);
117 void ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx); 123 void ResetGyroscopeZeroDriftMode(HLERequestContext& ctx);
118 void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx); 124 void IsSixAxisSensorAtRest(HLERequestContext& ctx);
119 void IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& ctx); 125 void IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx);
120 void EnableSixAxisSensorUnalteredPassthrough(Kernel::HLERequestContext& ctx); 126 void EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx);
121 void IsSixAxisSensorUnalteredPassthroughEnabled(Kernel::HLERequestContext& ctx); 127 void IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx);
122 void LoadSixAxisSensorCalibrationParameter(Kernel::HLERequestContext& ctx); 128 void LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx);
123 void GetSixAxisSensorIcInformation(Kernel::HLERequestContext& ctx); 129 void GetSixAxisSensorIcInformation(HLERequestContext& ctx);
124 void ResetIsSixAxisSensorDeviceNewlyAssigned(Kernel::HLERequestContext& ctx); 130 void ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx);
125 void ActivateGesture(Kernel::HLERequestContext& ctx); 131 void ActivateGesture(HLERequestContext& ctx);
126 void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx); 132 void SetSupportedNpadStyleSet(HLERequestContext& ctx);
127 void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx); 133 void GetSupportedNpadStyleSet(HLERequestContext& ctx);
128 void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx); 134 void SetSupportedNpadIdType(HLERequestContext& ctx);
129 void ActivateNpad(Kernel::HLERequestContext& ctx); 135 void ActivateNpad(HLERequestContext& ctx);
130 void DeactivateNpad(Kernel::HLERequestContext& ctx); 136 void DeactivateNpad(HLERequestContext& ctx);
131 void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx); 137 void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx);
132 void DisconnectNpad(Kernel::HLERequestContext& ctx); 138 void DisconnectNpad(HLERequestContext& ctx);
133 void GetPlayerLedPattern(Kernel::HLERequestContext& ctx); 139 void GetPlayerLedPattern(HLERequestContext& ctx);
134 void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx); 140 void ActivateNpadWithRevision(HLERequestContext& ctx);
135 void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx); 141 void SetNpadJoyHoldType(HLERequestContext& ctx);
136 void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx); 142 void GetNpadJoyHoldType(HLERequestContext& ctx);
137 void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx); 143 void SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx);
138 void SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx); 144 void SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx);
139 void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx); 145 void SetNpadJoyAssignmentModeDual(HLERequestContext& ctx);
140 void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx); 146 void MergeSingleJoyAsDualJoy(HLERequestContext& ctx);
141 void StartLrAssignmentMode(Kernel::HLERequestContext& ctx); 147 void StartLrAssignmentMode(HLERequestContext& ctx);
142 void StopLrAssignmentMode(Kernel::HLERequestContext& ctx); 148 void StopLrAssignmentMode(HLERequestContext& ctx);
143 void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); 149 void SetNpadHandheldActivationMode(HLERequestContext& ctx);
144 void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); 150 void GetNpadHandheldActivationMode(HLERequestContext& ctx);
145 void SwapNpadAssignment(Kernel::HLERequestContext& ctx); 151 void SwapNpadAssignment(HLERequestContext& ctx);
146 void IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx); 152 void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx);
147 void EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx); 153 void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx);
148 void SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx); 154 void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx);
149 void SetNpadCaptureButtonAssignment(Kernel::HLERequestContext& ctx); 155 void SetNpadCaptureButtonAssignment(HLERequestContext& ctx);
150 void ClearNpadCaptureButtonAssignment(Kernel::HLERequestContext& ctx); 156 void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx);
151 void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx); 157 void GetVibrationDeviceInfo(HLERequestContext& ctx);
152 void SendVibrationValue(Kernel::HLERequestContext& ctx); 158 void SendVibrationValue(HLERequestContext& ctx);
153 void GetActualVibrationValue(Kernel::HLERequestContext& ctx); 159 void GetActualVibrationValue(HLERequestContext& ctx);
154 void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx); 160 void CreateActiveVibrationDeviceList(HLERequestContext& ctx);
155 void PermitVibration(Kernel::HLERequestContext& ctx); 161 void PermitVibration(HLERequestContext& ctx);
156 void IsVibrationPermitted(Kernel::HLERequestContext& ctx); 162 void IsVibrationPermitted(HLERequestContext& ctx);
157 void SendVibrationValues(Kernel::HLERequestContext& ctx); 163 void SendVibrationValues(HLERequestContext& ctx);
158 void SendVibrationGcErmCommand(Kernel::HLERequestContext& ctx); 164 void SendVibrationGcErmCommand(HLERequestContext& ctx);
159 void GetActualVibrationGcErmCommand(Kernel::HLERequestContext& ctx); 165 void GetActualVibrationGcErmCommand(HLERequestContext& ctx);
160 void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx); 166 void BeginPermitVibrationSession(HLERequestContext& ctx);
161 void EndPermitVibrationSession(Kernel::HLERequestContext& ctx); 167 void EndPermitVibrationSession(HLERequestContext& ctx);
162 void IsVibrationDeviceMounted(Kernel::HLERequestContext& ctx); 168 void IsVibrationDeviceMounted(HLERequestContext& ctx);
163 void ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx); 169 void ActivateConsoleSixAxisSensor(HLERequestContext& ctx);
164 void StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx); 170 void StartConsoleSixAxisSensor(HLERequestContext& ctx);
165 void StopConsoleSixAxisSensor(Kernel::HLERequestContext& ctx); 171 void StopConsoleSixAxisSensor(HLERequestContext& ctx);
166 void ActivateSevenSixAxisSensor(Kernel::HLERequestContext& ctx); 172 void ActivateSevenSixAxisSensor(HLERequestContext& ctx);
167 void StartSevenSixAxisSensor(Kernel::HLERequestContext& ctx); 173 void StartSevenSixAxisSensor(HLERequestContext& ctx);
168 void StopSevenSixAxisSensor(Kernel::HLERequestContext& ctx); 174 void StopSevenSixAxisSensor(HLERequestContext& ctx);
169 void InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx); 175 void InitializeSevenSixAxisSensor(HLERequestContext& ctx);
170 void FinalizeSevenSixAxisSensor(Kernel::HLERequestContext& ctx); 176 void FinalizeSevenSixAxisSensor(HLERequestContext& ctx);
171 void ResetSevenSixAxisSensorTimestamp(Kernel::HLERequestContext& ctx); 177 void ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx);
172 void IsUsbFullKeyControllerEnabled(Kernel::HLERequestContext& ctx); 178 void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
173 void GetPalmaConnectionHandle(Kernel::HLERequestContext& ctx); 179 void GetPalmaConnectionHandle(HLERequestContext& ctx);
174 void InitializePalma(Kernel::HLERequestContext& ctx); 180 void InitializePalma(HLERequestContext& ctx);
175 void AcquirePalmaOperationCompleteEvent(Kernel::HLERequestContext& ctx); 181 void AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx);
176 void GetPalmaOperationInfo(Kernel::HLERequestContext& ctx); 182 void GetPalmaOperationInfo(HLERequestContext& ctx);
177 void PlayPalmaActivity(Kernel::HLERequestContext& ctx); 183 void PlayPalmaActivity(HLERequestContext& ctx);
178 void SetPalmaFrModeType(Kernel::HLERequestContext& ctx); 184 void SetPalmaFrModeType(HLERequestContext& ctx);
179 void ReadPalmaStep(Kernel::HLERequestContext& ctx); 185 void ReadPalmaStep(HLERequestContext& ctx);
180 void EnablePalmaStep(Kernel::HLERequestContext& ctx); 186 void EnablePalmaStep(HLERequestContext& ctx);
181 void ResetPalmaStep(Kernel::HLERequestContext& ctx); 187 void ResetPalmaStep(HLERequestContext& ctx);
182 void ReadPalmaApplicationSection(Kernel::HLERequestContext& ctx); 188 void ReadPalmaApplicationSection(HLERequestContext& ctx);
183 void WritePalmaApplicationSection(Kernel::HLERequestContext& ctx); 189 void WritePalmaApplicationSection(HLERequestContext& ctx);
184 void ReadPalmaUniqueCode(Kernel::HLERequestContext& ctx); 190 void ReadPalmaUniqueCode(HLERequestContext& ctx);
185 void SetPalmaUniqueCodeInvalid(Kernel::HLERequestContext& ctx); 191 void SetPalmaUniqueCodeInvalid(HLERequestContext& ctx);
186 void WritePalmaActivityEntry(Kernel::HLERequestContext& ctx); 192 void WritePalmaActivityEntry(HLERequestContext& ctx);
187 void WritePalmaRgbLedPatternEntry(Kernel::HLERequestContext& ctx); 193 void WritePalmaRgbLedPatternEntry(HLERequestContext& ctx);
188 void WritePalmaWaveEntry(Kernel::HLERequestContext& ctx); 194 void WritePalmaWaveEntry(HLERequestContext& ctx);
189 void SetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx); 195 void SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
190 void GetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx); 196 void GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
191 void SuspendPalmaFeature(Kernel::HLERequestContext& ctx); 197 void SuspendPalmaFeature(HLERequestContext& ctx);
192 void GetPalmaOperationResult(Kernel::HLERequestContext& ctx); 198 void GetPalmaOperationResult(HLERequestContext& ctx);
193 void ReadPalmaPlayLog(Kernel::HLERequestContext& ctx); 199 void ReadPalmaPlayLog(HLERequestContext& ctx);
194 void ResetPalmaPlayLog(Kernel::HLERequestContext& ctx); 200 void ResetPalmaPlayLog(HLERequestContext& ctx);
195 void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx); 201 void SetIsPalmaAllConnectable(HLERequestContext& ctx);
196 void SetIsPalmaPairedConnectable(Kernel::HLERequestContext& ctx); 202 void SetIsPalmaPairedConnectable(HLERequestContext& ctx);
197 void PairPalma(Kernel::HLERequestContext& ctx); 203 void PairPalma(HLERequestContext& ctx);
198 void SetPalmaBoostMode(Kernel::HLERequestContext& ctx); 204 void SetPalmaBoostMode(HLERequestContext& ctx);
199 void CancelWritePalmaWaveEntry(Kernel::HLERequestContext& ctx); 205 void CancelWritePalmaWaveEntry(HLERequestContext& ctx);
200 void EnablePalmaBoostMode(Kernel::HLERequestContext& ctx); 206 void EnablePalmaBoostMode(HLERequestContext& ctx);
201 void GetPalmaBluetoothAddress(Kernel::HLERequestContext& ctx); 207 void GetPalmaBluetoothAddress(HLERequestContext& ctx);
202 void SetDisallowedPalmaConnection(Kernel::HLERequestContext& ctx); 208 void SetDisallowedPalmaConnection(HLERequestContext& ctx);
203 void SetNpadCommunicationMode(Kernel::HLERequestContext& ctx); 209 void SetNpadCommunicationMode(HLERequestContext& ctx);
204 void GetNpadCommunicationMode(Kernel::HLERequestContext& ctx); 210 void GetNpadCommunicationMode(HLERequestContext& ctx);
205 void SetTouchScreenConfiguration(Kernel::HLERequestContext& ctx); 211 void SetTouchScreenConfiguration(HLERequestContext& ctx);
206 void IsFirmwareUpdateNeededForNotification(Kernel::HLERequestContext& ctx); 212 void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
207 213
208 std::shared_ptr<IAppletResource> applet_resource; 214 std::shared_ptr<IAppletResource> applet_resource;
209 215
210 KernelHelpers::ServiceContext service_context; 216 KernelHelpers::ServiceContext service_context;
211}; 217};
212 218
213/// Registers all HID services with the specified service manager. 219void LoopProcess(Core::System& system);
214void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
215 220
216} // namespace Service::HID 221} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp
index 8dbb2cf50..5604a6fda 100644
--- a/src/core/hle/service/hid/hidbus.cpp
+++ b/src/core/hle/service/hid/hidbus.cpp
@@ -7,7 +7,6 @@
7#include "core/core_timing.h" 7#include "core/core_timing.h"
8#include "core/core_timing_util.h" 8#include "core/core_timing_util.h"
9#include "core/hid/hid_types.h" 9#include "core/hid/hid_types.h"
10#include "core/hle/ipc_helpers.h"
11#include "core/hle/kernel/k_event.h" 10#include "core/hle/kernel/k_event.h"
12#include "core/hle/kernel/k_readable_event.h" 11#include "core/hle/kernel/k_readable_event.h"
13#include "core/hle/kernel/k_shared_memory.h" 12#include "core/hle/kernel/k_shared_memory.h"
@@ -16,6 +15,7 @@
16#include "core/hle/service/hid/hidbus/ringcon.h" 15#include "core/hle/service/hid/hidbus/ringcon.h"
17#include "core/hle/service/hid/hidbus/starlink.h" 16#include "core/hle/service/hid/hidbus/starlink.h"
18#include "core/hle/service/hid/hidbus/stubbed.h" 17#include "core/hle/service/hid/hidbus/stubbed.h"
18#include "core/hle/service/ipc_helpers.h"
19#include "core/hle/service/service.h" 19#include "core/hle/service/service.h"
20#include "core/memory.h" 20#include "core/memory.h"
21 21
@@ -99,7 +99,7 @@ std::optional<std::size_t> HidBus::GetDeviceIndexFromHandle(BusHandle handle) co
99 return std::nullopt; 99 return std::nullopt;
100} 100}
101 101
102void HidBus::GetBusHandle(Kernel::HLERequestContext& ctx) { 102void HidBus::GetBusHandle(HLERequestContext& ctx) {
103 IPC::RequestParser rp{ctx}; 103 IPC::RequestParser rp{ctx};
104 struct Parameters { 104 struct Parameters {
105 Core::HID::NpadIdType npad_id; 105 Core::HID::NpadIdType npad_id;
@@ -165,7 +165,7 @@ void HidBus::GetBusHandle(Kernel::HLERequestContext& ctx) {
165 rb.PushRaw(out_data); 165 rb.PushRaw(out_data);
166} 166}
167 167
168void HidBus::IsExternalDeviceConnected(Kernel::HLERequestContext& ctx) { 168void HidBus::IsExternalDeviceConnected(HLERequestContext& ctx) {
169 IPC::RequestParser rp{ctx}; 169 IPC::RequestParser rp{ctx};
170 const auto bus_handle_{rp.PopRaw<BusHandle>()}; 170 const auto bus_handle_{rp.PopRaw<BusHandle>()};
171 171
@@ -193,7 +193,7 @@ void HidBus::IsExternalDeviceConnected(Kernel::HLERequestContext& ctx) {
193 return; 193 return;
194} 194}
195 195
196void HidBus::Initialize(Kernel::HLERequestContext& ctx) { 196void HidBus::Initialize(HLERequestContext& ctx) {
197 IPC::RequestParser rp{ctx}; 197 IPC::RequestParser rp{ctx};
198 const auto bus_handle_{rp.PopRaw<BusHandle>()}; 198 const auto bus_handle_{rp.PopRaw<BusHandle>()};
199 const auto applet_resource_user_id{rp.Pop<u64>()}; 199 const auto applet_resource_user_id{rp.Pop<u64>()};
@@ -245,7 +245,7 @@ void HidBus::Initialize(Kernel::HLERequestContext& ctx) {
245 return; 245 return;
246} 246}
247 247
248void HidBus::Finalize(Kernel::HLERequestContext& ctx) { 248void HidBus::Finalize(HLERequestContext& ctx) {
249 IPC::RequestParser rp{ctx}; 249 IPC::RequestParser rp{ctx};
250 const auto bus_handle_{rp.PopRaw<BusHandle>()}; 250 const auto bus_handle_{rp.PopRaw<BusHandle>()};
251 const auto applet_resource_user_id{rp.Pop<u64>()}; 251 const auto applet_resource_user_id{rp.Pop<u64>()};
@@ -284,7 +284,7 @@ void HidBus::Finalize(Kernel::HLERequestContext& ctx) {
284 return; 284 return;
285} 285}
286 286
287void HidBus::EnableExternalDevice(Kernel::HLERequestContext& ctx) { 287void HidBus::EnableExternalDevice(HLERequestContext& ctx) {
288 IPC::RequestParser rp{ctx}; 288 IPC::RequestParser rp{ctx};
289 struct Parameters { 289 struct Parameters {
290 bool enable; 290 bool enable;
@@ -322,7 +322,7 @@ void HidBus::EnableExternalDevice(Kernel::HLERequestContext& ctx) {
322 return; 322 return;
323} 323}
324 324
325void HidBus::GetExternalDeviceId(Kernel::HLERequestContext& ctx) { 325void HidBus::GetExternalDeviceId(HLERequestContext& ctx) {
326 IPC::RequestParser rp{ctx}; 326 IPC::RequestParser rp{ctx};
327 const auto bus_handle_{rp.PopRaw<BusHandle>()}; 327 const auto bus_handle_{rp.PopRaw<BusHandle>()};
328 328
@@ -349,7 +349,7 @@ void HidBus::GetExternalDeviceId(Kernel::HLERequestContext& ctx) {
349 return; 349 return;
350} 350}
351 351
352void HidBus::SendCommandAsync(Kernel::HLERequestContext& ctx) { 352void HidBus::SendCommandAsync(HLERequestContext& ctx) {
353 IPC::RequestParser rp{ctx}; 353 IPC::RequestParser rp{ctx};
354 const auto data = ctx.ReadBuffer(); 354 const auto data = ctx.ReadBuffer();
355 const auto bus_handle_{rp.PopRaw<BusHandle>()}; 355 const auto bus_handle_{rp.PopRaw<BusHandle>()};
@@ -377,7 +377,7 @@ void HidBus::SendCommandAsync(Kernel::HLERequestContext& ctx) {
377 return; 377 return;
378}; 378};
379 379
380void HidBus::GetSendCommandAsynceResult(Kernel::HLERequestContext& ctx) { 380void HidBus::GetSendCommandAsynceResult(HLERequestContext& ctx) {
381 IPC::RequestParser rp{ctx}; 381 IPC::RequestParser rp{ctx};
382 const auto bus_handle_{rp.PopRaw<BusHandle>()}; 382 const auto bus_handle_{rp.PopRaw<BusHandle>()};
383 383
@@ -406,7 +406,7 @@ void HidBus::GetSendCommandAsynceResult(Kernel::HLERequestContext& ctx) {
406 return; 406 return;
407}; 407};
408 408
409void HidBus::SetEventForSendCommandAsycResult(Kernel::HLERequestContext& ctx) { 409void HidBus::SetEventForSendCommandAsycResult(HLERequestContext& ctx) {
410 IPC::RequestParser rp{ctx}; 410 IPC::RequestParser rp{ctx};
411 const auto bus_handle_{rp.PopRaw<BusHandle>()}; 411 const auto bus_handle_{rp.PopRaw<BusHandle>()};
412 412
@@ -432,7 +432,7 @@ void HidBus::SetEventForSendCommandAsycResult(Kernel::HLERequestContext& ctx) {
432 return; 432 return;
433}; 433};
434 434
435void HidBus::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { 435void HidBus::GetSharedMemoryHandle(HLERequestContext& ctx) {
436 LOG_DEBUG(Service_HID, "called"); 436 LOG_DEBUG(Service_HID, "called");
437 437
438 IPC::ResponseBuilder rb{ctx, 2, 1}; 438 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -440,7 +440,7 @@ void HidBus::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
440 rb.PushCopyObjects(&system.Kernel().GetHidBusSharedMem()); 440 rb.PushCopyObjects(&system.Kernel().GetHidBusSharedMem());
441} 441}
442 442
443void HidBus::EnableJoyPollingReceiveMode(Kernel::HLERequestContext& ctx) { 443void HidBus::EnableJoyPollingReceiveMode(HLERequestContext& ctx) {
444 IPC::RequestParser rp{ctx}; 444 IPC::RequestParser rp{ctx};
445 const auto t_mem_size{rp.Pop<u32>()}; 445 const auto t_mem_size{rp.Pop<u32>()};
446 const auto t_mem_handle{ctx.GetCopyHandle(0)}; 446 const auto t_mem_handle{ctx.GetCopyHandle(0)};
@@ -472,7 +472,7 @@ void HidBus::EnableJoyPollingReceiveMode(Kernel::HLERequestContext& ctx) {
472 if (device_index) { 472 if (device_index) {
473 auto& device = devices[device_index.value()].device; 473 auto& device = devices[device_index.value()].device;
474 device->SetPollingMode(polling_mode_); 474 device->SetPollingMode(polling_mode_);
475 device->SetTransferMemoryPointer(system.Memory().GetPointer(t_mem->GetSourceAddress())); 475 device->SetTransferMemoryAddress(t_mem->GetSourceAddress());
476 476
477 IPC::ResponseBuilder rb{ctx, 2}; 477 IPC::ResponseBuilder rb{ctx, 2};
478 rb.Push(ResultSuccess); 478 rb.Push(ResultSuccess);
@@ -485,7 +485,7 @@ void HidBus::EnableJoyPollingReceiveMode(Kernel::HLERequestContext& ctx) {
485 return; 485 return;
486} 486}
487 487
488void HidBus::DisableJoyPollingReceiveMode(Kernel::HLERequestContext& ctx) { 488void HidBus::DisableJoyPollingReceiveMode(HLERequestContext& ctx) {
489 IPC::RequestParser rp{ctx}; 489 IPC::RequestParser rp{ctx};
490 const auto bus_handle_{rp.PopRaw<BusHandle>()}; 490 const auto bus_handle_{rp.PopRaw<BusHandle>()};
491 491
@@ -512,7 +512,7 @@ void HidBus::DisableJoyPollingReceiveMode(Kernel::HLERequestContext& ctx) {
512 return; 512 return;
513} 513}
514 514
515void HidBus::SetStatusManagerType(Kernel::HLERequestContext& ctx) { 515void HidBus::SetStatusManagerType(HLERequestContext& ctx) {
516 IPC::RequestParser rp{ctx}; 516 IPC::RequestParser rp{ctx};
517 const auto manager_type{rp.PopEnum<StatusManagerType>()}; 517 const auto manager_type{rp.PopEnum<StatusManagerType>()};
518 518
diff --git a/src/core/hle/service/hid/hidbus.h b/src/core/hle/service/hid/hidbus.h
index 91c99b01f..c29b5e882 100644
--- a/src/core/hle/service/hid/hidbus.h
+++ b/src/core/hle/service/hid/hidbus.h
@@ -94,19 +94,19 @@ private:
94 std::unique_ptr<HidbusBase> device{nullptr}; 94 std::unique_ptr<HidbusBase> device{nullptr};
95 }; 95 };
96 96
97 void GetBusHandle(Kernel::HLERequestContext& ctx); 97 void GetBusHandle(HLERequestContext& ctx);
98 void IsExternalDeviceConnected(Kernel::HLERequestContext& ctx); 98 void IsExternalDeviceConnected(HLERequestContext& ctx);
99 void Initialize(Kernel::HLERequestContext& ctx); 99 void Initialize(HLERequestContext& ctx);
100 void Finalize(Kernel::HLERequestContext& ctx); 100 void Finalize(HLERequestContext& ctx);
101 void EnableExternalDevice(Kernel::HLERequestContext& ctx); 101 void EnableExternalDevice(HLERequestContext& ctx);
102 void GetExternalDeviceId(Kernel::HLERequestContext& ctx); 102 void GetExternalDeviceId(HLERequestContext& ctx);
103 void SendCommandAsync(Kernel::HLERequestContext& ctx); 103 void SendCommandAsync(HLERequestContext& ctx);
104 void GetSendCommandAsynceResult(Kernel::HLERequestContext& ctx); 104 void GetSendCommandAsynceResult(HLERequestContext& ctx);
105 void SetEventForSendCommandAsycResult(Kernel::HLERequestContext& ctx); 105 void SetEventForSendCommandAsycResult(HLERequestContext& ctx);
106 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); 106 void GetSharedMemoryHandle(HLERequestContext& ctx);
107 void EnableJoyPollingReceiveMode(Kernel::HLERequestContext& ctx); 107 void EnableJoyPollingReceiveMode(HLERequestContext& ctx);
108 void DisableJoyPollingReceiveMode(Kernel::HLERequestContext& ctx); 108 void DisableJoyPollingReceiveMode(HLERequestContext& ctx);
109 void SetStatusManagerType(Kernel::HLERequestContext& ctx); 109 void SetStatusManagerType(HLERequestContext& ctx);
110 110
111 void UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 111 void UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
112 std::optional<std::size_t> GetDeviceIndexFromHandle(BusHandle handle) const; 112 std::optional<std::size_t> GetDeviceIndexFromHandle(BusHandle handle) const;
@@ -115,8 +115,7 @@ private:
115 void MakeDevice(BusHandle handle) { 115 void MakeDevice(BusHandle handle) {
116 const auto device_index = GetDeviceIndexFromHandle(handle); 116 const auto device_index = GetDeviceIndexFromHandle(handle);
117 if (device_index) { 117 if (device_index) {
118 devices[device_index.value()].device = 118 devices[device_index.value()].device = std::make_unique<T>(system, service_context);
119 std::make_unique<T>(system.HIDCore(), service_context);
120 } 119 }
121 } 120 }
122 121
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.cpp b/src/core/hle/service/hid/hidbus/hidbus_base.cpp
index b569b3c20..dfd23ec04 100644
--- a/src/core/hle/service/hid/hidbus/hidbus_base.cpp
+++ b/src/core/hle/service/hid/hidbus/hidbus_base.cpp
@@ -9,8 +9,8 @@
9 9
10namespace Service::HID { 10namespace Service::HID {
11 11
12HidbusBase::HidbusBase(KernelHelpers::ServiceContext& service_context_) 12HidbusBase::HidbusBase(Core::System& system_, KernelHelpers::ServiceContext& service_context_)
13 : service_context(service_context_) { 13 : system(system_), service_context(service_context_) {
14 send_command_async_event = service_context.CreateEvent("hidbus:SendCommandAsyncEvent"); 14 send_command_async_event = service_context.CreateEvent("hidbus:SendCommandAsyncEvent");
15} 15}
16HidbusBase::~HidbusBase() = default; 16HidbusBase::~HidbusBase() = default;
@@ -59,8 +59,7 @@ void HidbusBase::DisablePollingMode() {
59 polling_mode_enabled = false; 59 polling_mode_enabled = false;
60} 60}
61 61
62void HidbusBase::SetTransferMemoryPointer(u8* t_mem) { 62void HidbusBase::SetTransferMemoryAddress(VAddr t_mem) {
63 is_transfer_memory_set = true;
64 transfer_memory = t_mem; 63 transfer_memory = t_mem;
65} 64}
66 65
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.h b/src/core/hle/service/hid/hidbus/hidbus_base.h
index 65e301137..26313264d 100644
--- a/src/core/hle/service/hid/hidbus/hidbus_base.h
+++ b/src/core/hle/service/hid/hidbus/hidbus_base.h
@@ -8,6 +8,10 @@
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/result.h" 9#include "core/hle/result.h"
10 10
11namespace Core {
12class System;
13}
14
11namespace Kernel { 15namespace Kernel {
12class KEvent; 16class KEvent;
13class KReadableEvent; 17class KReadableEvent;
@@ -106,7 +110,7 @@ static_assert(sizeof(ButtonOnlyPollingDataAccessor) == 0x2F0,
106 110
107class HidbusBase { 111class HidbusBase {
108public: 112public:
109 explicit HidbusBase(KernelHelpers::ServiceContext& service_context_); 113 explicit HidbusBase(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
110 virtual ~HidbusBase(); 114 virtual ~HidbusBase();
111 115
112 void ActivateDevice(); 116 void ActivateDevice();
@@ -134,7 +138,7 @@ public:
134 void DisablePollingMode(); 138 void DisablePollingMode();
135 139
136 // Called on EnableJoyPollingReceiveMode 140 // Called on EnableJoyPollingReceiveMode
137 void SetTransferMemoryPointer(u8* t_mem); 141 void SetTransferMemoryAddress(VAddr t_mem);
138 142
139 Kernel::KReadableEvent& GetSendCommandAsycEvent() const; 143 Kernel::KReadableEvent& GetSendCommandAsycEvent() const;
140 144
@@ -170,9 +174,9 @@ protected:
170 JoyEnableSixAxisDataAccessor enable_sixaxis_data{}; 174 JoyEnableSixAxisDataAccessor enable_sixaxis_data{};
171 ButtonOnlyPollingDataAccessor button_only_data{}; 175 ButtonOnlyPollingDataAccessor button_only_data{};
172 176
173 u8* transfer_memory{nullptr}; 177 VAddr transfer_memory{};
174 bool is_transfer_memory_set{};
175 178
179 Core::System& system;
176 Kernel::KEvent* send_command_async_event; 180 Kernel::KEvent* send_command_async_event;
177 KernelHelpers::ServiceContext& service_context; 181 KernelHelpers::ServiceContext& service_context;
178}; 182};
diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp
index 35847cbdd..65a2dd521 100644
--- a/src/core/hle/service/hid/hidbus/ringcon.cpp
+++ b/src/core/hle/service/hid/hidbus/ringcon.cpp
@@ -1,18 +1,20 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h"
4#include "core/hid/emulated_controller.h" 5#include "core/hid/emulated_controller.h"
5#include "core/hid/hid_core.h" 6#include "core/hid/hid_core.h"
6#include "core/hle/kernel/k_event.h" 7#include "core/hle/kernel/k_event.h"
7#include "core/hle/kernel/k_readable_event.h" 8#include "core/hle/kernel/k_readable_event.h"
8#include "core/hle/service/hid/hidbus/ringcon.h" 9#include "core/hle/service/hid/hidbus/ringcon.h"
10#include "core/memory.h"
9 11
10namespace Service::HID { 12namespace Service::HID {
11 13
12RingController::RingController(Core::HID::HIDCore& hid_core_, 14RingController::RingController(Core::System& system_,
13 KernelHelpers::ServiceContext& service_context_) 15 KernelHelpers::ServiceContext& service_context_)
14 : HidbusBase(service_context_) { 16 : HidbusBase(system_, service_context_) {
15 input = hid_core_.GetEmulatedController(Core::HID::NpadIdType::Player1); 17 input = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
16} 18}
17 19
18RingController::~RingController() = default; 20RingController::~RingController() = default;
@@ -38,7 +40,7 @@ void RingController::OnUpdate() {
38 return; 40 return;
39 } 41 }
40 42
41 if (!polling_mode_enabled || !is_transfer_memory_set) { 43 if (!polling_mode_enabled || transfer_memory == 0) {
42 return; 44 return;
43 } 45 }
44 46
@@ -62,7 +64,8 @@ void RingController::OnUpdate() {
62 curr_entry.polling_data.out_size = sizeof(ringcon_value); 64 curr_entry.polling_data.out_size = sizeof(ringcon_value);
63 std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value)); 65 std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value));
64 66
65 std::memcpy(transfer_memory, &enable_sixaxis_data, sizeof(enable_sixaxis_data)); 67 system.Memory().WriteBlock(transfer_memory, &enable_sixaxis_data,
68 sizeof(enable_sixaxis_data));
66 break; 69 break;
67 } 70 }
68 default: 71 default:
diff --git a/src/core/hle/service/hid/hidbus/ringcon.h b/src/core/hle/service/hid/hidbus/ringcon.h
index c2fb386b1..f42f3ea41 100644
--- a/src/core/hle/service/hid/hidbus/ringcon.h
+++ b/src/core/hle/service/hid/hidbus/ringcon.h
@@ -17,8 +17,7 @@ namespace Service::HID {
17 17
18class RingController final : public HidbusBase { 18class RingController final : public HidbusBase {
19public: 19public:
20 explicit RingController(Core::HID::HIDCore& hid_core_, 20 explicit RingController(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
21 KernelHelpers::ServiceContext& service_context_);
22 ~RingController() override; 21 ~RingController() override;
23 22
24 void OnInit() override; 23 void OnInit() override;
diff --git a/src/core/hle/service/hid/hidbus/starlink.cpp b/src/core/hle/service/hid/hidbus/starlink.cpp
index d0e760314..36573274e 100644
--- a/src/core/hle/service/hid/hidbus/starlink.cpp
+++ b/src/core/hle/service/hid/hidbus/starlink.cpp
@@ -8,8 +8,8 @@
8namespace Service::HID { 8namespace Service::HID {
9constexpr u8 DEVICE_ID = 0x28; 9constexpr u8 DEVICE_ID = 0x28;
10 10
11Starlink::Starlink(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_) 11Starlink::Starlink(Core::System& system_, KernelHelpers::ServiceContext& service_context_)
12 : HidbusBase(service_context_) {} 12 : HidbusBase(system_, service_context_) {}
13Starlink::~Starlink() = default; 13Starlink::~Starlink() = default;
14 14
15void Starlink::OnInit() { 15void Starlink::OnInit() {
@@ -27,7 +27,7 @@ void Starlink::OnUpdate() {
27 if (!device_enabled) { 27 if (!device_enabled) {
28 return; 28 return;
29 } 29 }
30 if (!polling_mode_enabled || !is_transfer_memory_set) { 30 if (!polling_mode_enabled || transfer_memory == 0) {
31 return; 31 return;
32 } 32 }
33 33
diff --git a/src/core/hle/service/hid/hidbus/starlink.h b/src/core/hle/service/hid/hidbus/starlink.h
index 07c800e6e..a276aa88f 100644
--- a/src/core/hle/service/hid/hidbus/starlink.h
+++ b/src/core/hle/service/hid/hidbus/starlink.h
@@ -14,8 +14,7 @@ namespace Service::HID {
14 14
15class Starlink final : public HidbusBase { 15class Starlink final : public HidbusBase {
16public: 16public:
17 explicit Starlink(Core::HID::HIDCore& hid_core_, 17 explicit Starlink(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
18 KernelHelpers::ServiceContext& service_context_);
19 ~Starlink() override; 18 ~Starlink() override;
20 19
21 void OnInit() override; 20 void OnInit() override;
diff --git a/src/core/hle/service/hid/hidbus/stubbed.cpp b/src/core/hle/service/hid/hidbus/stubbed.cpp
index 07632c872..8160b7218 100644
--- a/src/core/hle/service/hid/hidbus/stubbed.cpp
+++ b/src/core/hle/service/hid/hidbus/stubbed.cpp
@@ -8,9 +8,8 @@
8namespace Service::HID { 8namespace Service::HID {
9constexpr u8 DEVICE_ID = 0xFF; 9constexpr u8 DEVICE_ID = 0xFF;
10 10
11HidbusStubbed::HidbusStubbed(Core::HID::HIDCore& hid_core_, 11HidbusStubbed::HidbusStubbed(Core::System& system_, KernelHelpers::ServiceContext& service_context_)
12 KernelHelpers::ServiceContext& service_context_) 12 : HidbusBase(system_, service_context_) {}
13 : HidbusBase(service_context_) {}
14HidbusStubbed::~HidbusStubbed() = default; 13HidbusStubbed::~HidbusStubbed() = default;
15 14
16void HidbusStubbed::OnInit() { 15void HidbusStubbed::OnInit() {
@@ -28,7 +27,7 @@ void HidbusStubbed::OnUpdate() {
28 if (!device_enabled) { 27 if (!device_enabled) {
29 return; 28 return;
30 } 29 }
31 if (!polling_mode_enabled || !is_transfer_memory_set) { 30 if (!polling_mode_enabled || transfer_memory == 0) {
32 return; 31 return;
33 } 32 }
34 33
diff --git a/src/core/hle/service/hid/hidbus/stubbed.h b/src/core/hle/service/hid/hidbus/stubbed.h
index 38eaa0ecc..2e58d42fc 100644
--- a/src/core/hle/service/hid/hidbus/stubbed.h
+++ b/src/core/hle/service/hid/hidbus/stubbed.h
@@ -14,8 +14,7 @@ namespace Service::HID {
14 14
15class HidbusStubbed final : public HidbusBase { 15class HidbusStubbed final : public HidbusBase {
16public: 16public:
17 explicit HidbusStubbed(Core::HID::HIDCore& hid_core_, 17 explicit HidbusStubbed(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
18 KernelHelpers::ServiceContext& service_context_);
19 ~HidbusStubbed() override; 18 ~HidbusStubbed() override;
20 19
21 void OnInit() override; 20 void OnInit() override;
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 3bd418e92..221c33b86 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -8,7 +8,6 @@
8#include "core/core_timing.h" 8#include "core/core_timing.h"
9#include "core/hid/emulated_controller.h" 9#include "core/hid/emulated_controller.h"
10#include "core/hid/hid_core.h" 10#include "core/hid/hid_core.h"
11#include "core/hle/ipc_helpers.h"
12#include "core/hle/kernel/k_shared_memory.h" 11#include "core/hle/kernel/k_shared_memory.h"
13#include "core/hle/kernel/k_transfer_memory.h" 12#include "core/hle/kernel/k_transfer_memory.h"
14#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
@@ -20,6 +19,7 @@
20#include "core/hle/service/hid/irsensor/moment_processor.h" 19#include "core/hle/service/hid/irsensor/moment_processor.h"
21#include "core/hle/service/hid/irsensor/pointing_processor.h" 20#include "core/hle/service/hid/irsensor/pointing_processor.h"
22#include "core/hle/service/hid/irsensor/tera_plugin_processor.h" 21#include "core/hle/service/hid/irsensor/tera_plugin_processor.h"
22#include "core/hle/service/ipc_helpers.h"
23#include "core/memory.h" 23#include "core/memory.h"
24 24
25namespace Service::IRS { 25namespace Service::IRS {
@@ -56,7 +56,7 @@ IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
56} 56}
57IRS::~IRS() = default; 57IRS::~IRS() = default;
58 58
59void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) { 59void IRS::ActivateIrsensor(HLERequestContext& ctx) {
60 IPC::RequestParser rp{ctx}; 60 IPC::RequestParser rp{ctx};
61 const auto applet_resource_user_id{rp.Pop<u64>()}; 61 const auto applet_resource_user_id{rp.Pop<u64>()};
62 62
@@ -67,7 +67,7 @@ void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) {
67 rb.Push(ResultSuccess); 67 rb.Push(ResultSuccess);
68} 68}
69 69
70void IRS::DeactivateIrsensor(Kernel::HLERequestContext& ctx) { 70void IRS::DeactivateIrsensor(HLERequestContext& ctx) {
71 IPC::RequestParser rp{ctx}; 71 IPC::RequestParser rp{ctx};
72 const auto applet_resource_user_id{rp.Pop<u64>()}; 72 const auto applet_resource_user_id{rp.Pop<u64>()};
73 73
@@ -78,7 +78,7 @@ void IRS::DeactivateIrsensor(Kernel::HLERequestContext& ctx) {
78 rb.Push(ResultSuccess); 78 rb.Push(ResultSuccess);
79} 79}
80 80
81void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) { 81void IRS::GetIrsensorSharedMemoryHandle(HLERequestContext& ctx) {
82 IPC::RequestParser rp{ctx}; 82 IPC::RequestParser rp{ctx};
83 const auto applet_resource_user_id{rp.Pop<u64>()}; 83 const auto applet_resource_user_id{rp.Pop<u64>()};
84 84
@@ -89,7 +89,7 @@ void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
89 rb.PushCopyObjects(&system.Kernel().GetIrsSharedMem()); 89 rb.PushCopyObjects(&system.Kernel().GetIrsSharedMem());
90} 90}
91 91
92void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) { 92void IRS::StopImageProcessor(HLERequestContext& ctx) {
93 IPC::RequestParser rp{ctx}; 93 IPC::RequestParser rp{ctx};
94 struct Parameters { 94 struct Parameters {
95 Core::IrSensor::IrCameraHandle camera_handle; 95 Core::IrSensor::IrCameraHandle camera_handle;
@@ -117,7 +117,7 @@ void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) {
117 rb.Push(result); 117 rb.Push(result);
118} 118}
119 119
120void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) { 120void IRS::RunMomentProcessor(HLERequestContext& ctx) {
121 IPC::RequestParser rp{ctx}; 121 IPC::RequestParser rp{ctx};
122 struct Parameters { 122 struct Parameters {
123 Core::IrSensor::IrCameraHandle camera_handle; 123 Core::IrSensor::IrCameraHandle camera_handle;
@@ -149,7 +149,7 @@ void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) {
149 rb.Push(result); 149 rb.Push(result);
150} 150}
151 151
152void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) { 152void IRS::RunClusteringProcessor(HLERequestContext& ctx) {
153 IPC::RequestParser rp{ctx}; 153 IPC::RequestParser rp{ctx};
154 struct Parameters { 154 struct Parameters {
155 Core::IrSensor::IrCameraHandle camera_handle; 155 Core::IrSensor::IrCameraHandle camera_handle;
@@ -182,7 +182,7 @@ void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) {
182 rb.Push(result); 182 rb.Push(result);
183} 183}
184 184
185void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) { 185void IRS::RunImageTransferProcessor(HLERequestContext& ctx) {
186 IPC::RequestParser rp{ctx}; 186 IPC::RequestParser rp{ctx};
187 struct Parameters { 187 struct Parameters {
188 Core::IrSensor::IrCameraHandle camera_handle; 188 Core::IrSensor::IrCameraHandle camera_handle;
@@ -208,8 +208,6 @@ void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
208 208
209 ASSERT_MSG(t_mem->GetSize() == parameters.transfer_memory_size, "t_mem has incorrect size"); 209 ASSERT_MSG(t_mem->GetSize() == parameters.transfer_memory_size, "t_mem has incorrect size");
210 210
211 u8* transfer_memory = system.Memory().GetPointer(t_mem->GetSourceAddress());
212
213 LOG_INFO(Service_IRS, 211 LOG_INFO(Service_IRS,
214 "called, npad_type={}, npad_id={}, transfer_memory_size={}, transfer_memory_size={}, " 212 "called, npad_type={}, npad_id={}, transfer_memory_size={}, transfer_memory_size={}, "
215 "applet_resource_user_id={}", 213 "applet_resource_user_id={}",
@@ -224,7 +222,7 @@ void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
224 auto& image_transfer_processor = 222 auto& image_transfer_processor =
225 GetProcessor<ImageTransferProcessor>(parameters.camera_handle); 223 GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
226 image_transfer_processor.SetConfig(parameters.processor_config); 224 image_transfer_processor.SetConfig(parameters.processor_config);
227 image_transfer_processor.SetTransferMemoryPointer(transfer_memory); 225 image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress());
228 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, 226 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
229 Common::Input::PollingMode::IR); 227 Common::Input::PollingMode::IR);
230 } 228 }
@@ -233,7 +231,7 @@ void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
233 rb.Push(result); 231 rb.Push(result);
234} 232}
235 233
236void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) { 234void IRS::GetImageTransferProcessorState(HLERequestContext& ctx) {
237 IPC::RequestParser rp{ctx}; 235 IPC::RequestParser rp{ctx};
238 struct Parameters { 236 struct Parameters {
239 Core::IrSensor::IrCameraHandle camera_handle; 237 Core::IrSensor::IrCameraHandle camera_handle;
@@ -274,7 +272,7 @@ void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) {
274 rb.PushRaw(state); 272 rb.PushRaw(state);
275} 273}
276 274
277void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) { 275void IRS::RunTeraPluginProcessor(HLERequestContext& ctx) {
278 IPC::RequestParser rp{ctx}; 276 IPC::RequestParser rp{ctx};
279 struct Parameters { 277 struct Parameters {
280 Core::IrSensor::IrCameraHandle camera_handle; 278 Core::IrSensor::IrCameraHandle camera_handle;
@@ -310,7 +308,7 @@ void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) {
310 rb.Push(result); 308 rb.Push(result);
311} 309}
312 310
313void IRS::GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx) { 311void IRS::GetNpadIrCameraHandle(HLERequestContext& ctx) {
314 IPC::RequestParser rp{ctx}; 312 IPC::RequestParser rp{ctx};
315 const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()}; 313 const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
316 314
@@ -334,7 +332,7 @@ void IRS::GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx) {
334 rb.PushRaw(camera_handle); 332 rb.PushRaw(camera_handle);
335} 333}
336 334
337void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) { 335void IRS::RunPointingProcessor(HLERequestContext& ctx) {
338 IPC::RequestParser rp{ctx}; 336 IPC::RequestParser rp{ctx};
339 const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()}; 337 const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
340 const auto processor_config{rp.PopRaw<Core::IrSensor::PackedPointingProcessorConfig>()}; 338 const auto processor_config{rp.PopRaw<Core::IrSensor::PackedPointingProcessorConfig>()};
@@ -361,7 +359,7 @@ void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) {
361 rb.Push(result); 359 rb.Push(result);
362} 360}
363 361
364void IRS::SuspendImageProcessor(Kernel::HLERequestContext& ctx) { 362void IRS::SuspendImageProcessor(HLERequestContext& ctx) {
365 IPC::RequestParser rp{ctx}; 363 IPC::RequestParser rp{ctx};
366 struct Parameters { 364 struct Parameters {
367 Core::IrSensor::IrCameraHandle camera_handle; 365 Core::IrSensor::IrCameraHandle camera_handle;
@@ -387,7 +385,7 @@ void IRS::SuspendImageProcessor(Kernel::HLERequestContext& ctx) {
387 rb.Push(result); 385 rb.Push(result);
388} 386}
389 387
390void IRS::CheckFirmwareVersion(Kernel::HLERequestContext& ctx) { 388void IRS::CheckFirmwareVersion(HLERequestContext& ctx) {
391 IPC::RequestParser rp{ctx}; 389 IPC::RequestParser rp{ctx};
392 const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()}; 390 const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
393 const auto mcu_version{rp.PopRaw<Core::IrSensor::PackedMcuVersion>()}; 391 const auto mcu_version{rp.PopRaw<Core::IrSensor::PackedMcuVersion>()};
@@ -409,7 +407,7 @@ void IRS::CheckFirmwareVersion(Kernel::HLERequestContext& ctx) {
409 rb.Push(result); 407 rb.Push(result);
410} 408}
411 409
412void IRS::SetFunctionLevel(Kernel::HLERequestContext& ctx) { 410void IRS::SetFunctionLevel(HLERequestContext& ctx) {
413 IPC::RequestParser rp{ctx}; 411 IPC::RequestParser rp{ctx};
414 const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()}; 412 const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
415 const auto function_level{rp.PopRaw<Core::IrSensor::PackedFunctionLevel>()}; 413 const auto function_level{rp.PopRaw<Core::IrSensor::PackedFunctionLevel>()};
@@ -431,7 +429,7 @@ void IRS::SetFunctionLevel(Kernel::HLERequestContext& ctx) {
431 rb.Push(result); 429 rb.Push(result);
432} 430}
433 431
434void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) { 432void IRS::RunImageTransferExProcessor(HLERequestContext& ctx) {
435 IPC::RequestParser rp{ctx}; 433 IPC::RequestParser rp{ctx};
436 struct Parameters { 434 struct Parameters {
437 Core::IrSensor::IrCameraHandle camera_handle; 435 Core::IrSensor::IrCameraHandle camera_handle;
@@ -448,8 +446,6 @@ void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
448 auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>( 446 auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
449 t_mem_handle); 447 t_mem_handle);
450 448
451 u8* transfer_memory = system.Memory().GetPointer(t_mem->GetSourceAddress());
452
453 LOG_INFO(Service_IRS, 449 LOG_INFO(Service_IRS,
454 "called, npad_type={}, npad_id={}, transfer_memory_size={}, " 450 "called, npad_type={}, npad_id={}, transfer_memory_size={}, "
455 "applet_resource_user_id={}", 451 "applet_resource_user_id={}",
@@ -464,7 +460,7 @@ void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
464 auto& image_transfer_processor = 460 auto& image_transfer_processor =
465 GetProcessor<ImageTransferProcessor>(parameters.camera_handle); 461 GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
466 image_transfer_processor.SetConfig(parameters.processor_config); 462 image_transfer_processor.SetConfig(parameters.processor_config);
467 image_transfer_processor.SetTransferMemoryPointer(transfer_memory); 463 image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress());
468 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, 464 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
469 Common::Input::PollingMode::IR); 465 Common::Input::PollingMode::IR);
470 } 466 }
@@ -473,7 +469,7 @@ void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
473 rb.Push(result); 469 rb.Push(result);
474} 470}
475 471
476void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) { 472void IRS::RunIrLedProcessor(HLERequestContext& ctx) {
477 IPC::RequestParser rp{ctx}; 473 IPC::RequestParser rp{ctx};
478 const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()}; 474 const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
479 const auto processor_config{rp.PopRaw<Core::IrSensor::PackedIrLedProcessorConfig>()}; 475 const auto processor_config{rp.PopRaw<Core::IrSensor::PackedIrLedProcessorConfig>()};
@@ -501,7 +497,7 @@ void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) {
501 rb.Push(result); 497 rb.Push(result);
502} 498}
503 499
504void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) { 500void IRS::StopImageProcessorAsync(HLERequestContext& ctx) {
505 IPC::RequestParser rp{ctx}; 501 IPC::RequestParser rp{ctx};
506 struct Parameters { 502 struct Parameters {
507 Core::IrSensor::IrCameraHandle camera_handle; 503 Core::IrSensor::IrCameraHandle camera_handle;
@@ -529,7 +525,7 @@ void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) {
529 rb.Push(result); 525 rb.Push(result);
530} 526}
531 527
532void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) { 528void IRS::ActivateIrsensorWithFunctionLevel(HLERequestContext& ctx) {
533 IPC::RequestParser rp{ctx}; 529 IPC::RequestParser rp{ctx};
534 struct Parameters { 530 struct Parameters {
535 Core::IrSensor::PackedFunctionLevel function_level; 531 Core::IrSensor::PackedFunctionLevel function_level;
diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h
index 2e6115c73..a8fa19025 100644
--- a/src/core/hle/service/hid/irs.h
+++ b/src/core/hle/service/hid/irs.h
@@ -38,24 +38,24 @@ private:
38 }; 38 };
39 static_assert(sizeof(StatusManager) == 0x8000, "StatusManager is an invalid size"); 39 static_assert(sizeof(StatusManager) == 0x8000, "StatusManager is an invalid size");
40 40
41 void ActivateIrsensor(Kernel::HLERequestContext& ctx); 41 void ActivateIrsensor(HLERequestContext& ctx);
42 void DeactivateIrsensor(Kernel::HLERequestContext& ctx); 42 void DeactivateIrsensor(HLERequestContext& ctx);
43 void GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx); 43 void GetIrsensorSharedMemoryHandle(HLERequestContext& ctx);
44 void StopImageProcessor(Kernel::HLERequestContext& ctx); 44 void StopImageProcessor(HLERequestContext& ctx);
45 void RunMomentProcessor(Kernel::HLERequestContext& ctx); 45 void RunMomentProcessor(HLERequestContext& ctx);
46 void RunClusteringProcessor(Kernel::HLERequestContext& ctx); 46 void RunClusteringProcessor(HLERequestContext& ctx);
47 void RunImageTransferProcessor(Kernel::HLERequestContext& ctx); 47 void RunImageTransferProcessor(HLERequestContext& ctx);
48 void GetImageTransferProcessorState(Kernel::HLERequestContext& ctx); 48 void GetImageTransferProcessorState(HLERequestContext& ctx);
49 void RunTeraPluginProcessor(Kernel::HLERequestContext& ctx); 49 void RunTeraPluginProcessor(HLERequestContext& ctx);
50 void GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx); 50 void GetNpadIrCameraHandle(HLERequestContext& ctx);
51 void RunPointingProcessor(Kernel::HLERequestContext& ctx); 51 void RunPointingProcessor(HLERequestContext& ctx);
52 void SuspendImageProcessor(Kernel::HLERequestContext& ctx); 52 void SuspendImageProcessor(HLERequestContext& ctx);
53 void CheckFirmwareVersion(Kernel::HLERequestContext& ctx); 53 void CheckFirmwareVersion(HLERequestContext& ctx);
54 void SetFunctionLevel(Kernel::HLERequestContext& ctx); 54 void SetFunctionLevel(HLERequestContext& ctx);
55 void RunImageTransferExProcessor(Kernel::HLERequestContext& ctx); 55 void RunImageTransferExProcessor(HLERequestContext& ctx);
56 void RunIrLedProcessor(Kernel::HLERequestContext& ctx); 56 void RunIrLedProcessor(HLERequestContext& ctx);
57 void StopImageProcessorAsync(Kernel::HLERequestContext& ctx); 57 void StopImageProcessorAsync(HLERequestContext& ctx);
58 void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx); 58 void ActivateIrsensorWithFunctionLevel(HLERequestContext& ctx);
59 59
60 Result IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const; 60 Result IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const;
61 Core::IrSensor::DeviceFormat& GetIrCameraSharedMemoryDeviceEntry( 61 Core::IrSensor::DeviceFormat& GetIrCameraSharedMemoryDeviceEntry(
@@ -80,7 +80,13 @@ private:
80 LOG_CRITICAL(Service_IRS, "Invalid index {}", index); 80 LOG_CRITICAL(Service_IRS, "Invalid index {}", index);
81 return; 81 return;
82 } 82 }
83 processors[index] = std::make_unique<T>(system.HIDCore(), device_state, index); 83
84 if constexpr (std::is_constructible_v<T, Core::System&, Core::IrSensor::DeviceFormat&,
85 std::size_t>) {
86 processors[index] = std::make_unique<T>(system, device_state, index);
87 } else {
88 processors[index] = std::make_unique<T>(system.HIDCore(), device_state, index);
89 }
84 } 90 }
85 91
86 template <typename T> 92 template <typename T>
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
index 98f0c579d..bc896a1e3 100644
--- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
+++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
@@ -1,16 +1,18 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include "core/core.h"
4#include "core/hid/emulated_controller.h" 5#include "core/hid/emulated_controller.h"
5#include "core/hid/hid_core.h" 6#include "core/hid/hid_core.h"
6#include "core/hle/service/hid/irsensor/image_transfer_processor.h" 7#include "core/hle/service/hid/irsensor/image_transfer_processor.h"
8#include "core/memory.h"
7 9
8namespace Service::IRS { 10namespace Service::IRS {
9ImageTransferProcessor::ImageTransferProcessor(Core::HID::HIDCore& hid_core_, 11ImageTransferProcessor::ImageTransferProcessor(Core::System& system_,
10 Core::IrSensor::DeviceFormat& device_format, 12 Core::IrSensor::DeviceFormat& device_format,
11 std::size_t npad_index) 13 std::size_t npad_index)
12 : device{device_format} { 14 : device{device_format}, system{system_} {
13 npad_device = hid_core_.GetEmulatedControllerByIndex(npad_index); 15 npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index);
14 16
15 Core::HID::ControllerUpdateCallback engine_callback{ 17 Core::HID::ControllerUpdateCallback engine_callback{
16 .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); }, 18 .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); },
@@ -43,7 +45,7 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
43 if (type != Core::HID::ControllerTriggerType::IrSensor) { 45 if (type != Core::HID::ControllerTriggerType::IrSensor) {
44 return; 46 return;
45 } 47 }
46 if (!is_transfer_memory_set) { 48 if (transfer_memory == 0) {
47 return; 49 return;
48 } 50 }
49 51
@@ -56,14 +58,16 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
56 if (camera_data.format != current_config.origin_format) { 58 if (camera_data.format != current_config.origin_format) {
57 LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format, 59 LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format,
58 current_config.origin_format); 60 current_config.origin_format);
59 memset(transfer_memory, 0, GetDataSize(current_config.trimming_format)); 61 system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
62 GetDataSize(current_config.trimming_format));
60 return; 63 return;
61 } 64 }
62 65
63 if (current_config.origin_format > current_config.trimming_format) { 66 if (current_config.origin_format > current_config.trimming_format) {
64 LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}", 67 LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}",
65 current_config.origin_format, current_config.trimming_format); 68 current_config.origin_format, current_config.trimming_format);
66 memset(transfer_memory, 0, GetDataSize(current_config.trimming_format)); 69 system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
70 GetDataSize(current_config.trimming_format));
67 return; 71 return;
68 } 72 }
69 73
@@ -80,7 +84,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
80 "Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})", 84 "Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})",
81 current_config.trimming_start_x, current_config.trimming_start_y, 85 current_config.trimming_start_x, current_config.trimming_start_y,
82 trimming_width, trimming_height, origin_width, origin_height); 86 trimming_width, trimming_height, origin_width, origin_height);
83 memset(transfer_memory, 0, GetDataSize(current_config.trimming_format)); 87 system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
88 GetDataSize(current_config.trimming_format));
84 return; 89 return;
85 } 90 }
86 91
@@ -94,7 +99,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
94 } 99 }
95 } 100 }
96 101
97 memcpy(transfer_memory, window_data.data(), GetDataSize(current_config.trimming_format)); 102 system.Memory().WriteBlock(transfer_memory, window_data.data(),
103 GetDataSize(current_config.trimming_format));
98 104
99 if (!IsProcessorActive()) { 105 if (!IsProcessorActive()) {
100 StartProcessor(); 106 StartProcessor();
@@ -134,8 +140,7 @@ void ImageTransferProcessor::SetConfig(
134 npad_device->SetCameraFormat(current_config.origin_format); 140 npad_device->SetCameraFormat(current_config.origin_format);
135} 141}
136 142
137void ImageTransferProcessor::SetTransferMemoryPointer(u8* t_mem) { 143void ImageTransferProcessor::SetTransferMemoryAddress(VAddr t_mem) {
138 is_transfer_memory_set = true;
139 transfer_memory = t_mem; 144 transfer_memory = t_mem;
140} 145}
141 146
@@ -143,7 +148,7 @@ Core::IrSensor::ImageTransferProcessorState ImageTransferProcessor::GetState(
143 std::vector<u8>& data) const { 148 std::vector<u8>& data) const {
144 const auto size = GetDataSize(current_config.trimming_format); 149 const auto size = GetDataSize(current_config.trimming_format);
145 data.resize(size); 150 data.resize(size);
146 memcpy(data.data(), transfer_memory, size); 151 system.Memory().ReadBlock(transfer_memory, data.data(), size);
147 return processor_state; 152 return processor_state;
148} 153}
149 154
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.h b/src/core/hle/service/hid/irsensor/image_transfer_processor.h
index 393df492d..7cfe04c8c 100644
--- a/src/core/hle/service/hid/irsensor/image_transfer_processor.h
+++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.h
@@ -7,6 +7,10 @@
7#include "core/hid/irs_types.h" 7#include "core/hid/irs_types.h"
8#include "core/hle/service/hid/irsensor/processor_base.h" 8#include "core/hle/service/hid/irsensor/processor_base.h"
9 9
10namespace Core {
11class System;
12}
13
10namespace Core::HID { 14namespace Core::HID {
11class EmulatedController; 15class EmulatedController;
12} // namespace Core::HID 16} // namespace Core::HID
@@ -14,7 +18,7 @@ class EmulatedController;
14namespace Service::IRS { 18namespace Service::IRS {
15class ImageTransferProcessor final : public ProcessorBase { 19class ImageTransferProcessor final : public ProcessorBase {
16public: 20public:
17 explicit ImageTransferProcessor(Core::HID::HIDCore& hid_core_, 21 explicit ImageTransferProcessor(Core::System& system_,
18 Core::IrSensor::DeviceFormat& device_format, 22 Core::IrSensor::DeviceFormat& device_format,
19 std::size_t npad_index); 23 std::size_t npad_index);
20 ~ImageTransferProcessor() override; 24 ~ImageTransferProcessor() override;
@@ -33,7 +37,7 @@ public:
33 void SetConfig(Core::IrSensor::PackedImageTransferProcessorExConfig config); 37 void SetConfig(Core::IrSensor::PackedImageTransferProcessorExConfig config);
34 38
35 // Transfer memory where the image data will be stored 39 // Transfer memory where the image data will be stored
36 void SetTransferMemoryPointer(u8* t_mem); 40 void SetTransferMemoryAddress(VAddr t_mem);
37 41
38 Core::IrSensor::ImageTransferProcessorState GetState(std::vector<u8>& data) const; 42 Core::IrSensor::ImageTransferProcessorState GetState(std::vector<u8>& data) const;
39 43
@@ -67,7 +71,7 @@ private:
67 Core::HID::EmulatedController* npad_device; 71 Core::HID::EmulatedController* npad_device;
68 int callback_key{}; 72 int callback_key{};
69 73
70 u8* transfer_memory = nullptr; 74 Core::System& system;
71 bool is_transfer_memory_set = false; 75 VAddr transfer_memory{};
72}; 76};
73} // namespace Service::IRS 77} // namespace Service::IRS
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/service/hle_ipc.cpp
index 494151eef..c221ffe11 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/service/hle_ipc.cpp
@@ -12,8 +12,6 @@
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/scratch_buffer.h" 14#include "common/scratch_buffer.h"
15#include "core/hle/ipc_helpers.h"
16#include "core/hle/kernel/hle_ipc.h"
17#include "core/hle/kernel/k_auto_object.h" 15#include "core/hle/kernel/k_auto_object.h"
18#include "core/hle/kernel/k_handle_table.h" 16#include "core/hle/kernel/k_handle_table.h"
19#include "core/hle/kernel/k_process.h" 17#include "core/hle/kernel/k_process.h"
@@ -21,36 +19,20 @@
21#include "core/hle/kernel/k_server_session.h" 19#include "core/hle/kernel/k_server_session.h"
22#include "core/hle/kernel/k_thread.h" 20#include "core/hle/kernel/k_thread.h"
23#include "core/hle/kernel/kernel.h" 21#include "core/hle/kernel/kernel.h"
24#include "core/hle/kernel/service_thread.h" 22#include "core/hle/service/hle_ipc.h"
23#include "core/hle/service/ipc_helpers.h"
25#include "core/memory.h" 24#include "core/memory.h"
26 25
27namespace Kernel { 26namespace Service {
28 27
29SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_, 28SessionRequestHandler::SessionRequestHandler(Kernel::KernelCore& kernel_, const char* service_name_)
30 ServiceThreadType thread_type) 29 : kernel{kernel_} {}
31 : kernel{kernel_}, service_thread{thread_type == ServiceThreadType::CreateNew
32 ? kernel.CreateServiceThread(service_name_)
33 : kernel.GetDefaultServiceThread()} {}
34 30
35SessionRequestHandler::~SessionRequestHandler() { 31SessionRequestHandler::~SessionRequestHandler() = default;
36 kernel.ReleaseServiceThread(service_thread);
37}
38
39void SessionRequestHandler::AcceptSession(KServerPort* server_port) {
40 auto* server_session = server_port->AcceptSession();
41 ASSERT(server_session != nullptr);
42
43 RegisterSession(server_session, std::make_shared<SessionRequestManager>(kernel));
44}
45
46void SessionRequestHandler::RegisterSession(KServerSession* server_session,
47 std::shared_ptr<SessionRequestManager> manager) {
48 manager->SetSessionHandler(shared_from_this());
49 service_thread.RegisterServerSession(server_session, manager);
50 server_session->Close();
51}
52 32
53SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kernel_} {} 33SessionRequestManager::SessionRequestManager(Kernel::KernelCore& kernel_,
34 ServerManager& server_manager_)
35 : kernel{kernel_}, server_manager{server_manager_} {}
54 36
55SessionRequestManager::~SessionRequestManager() = default; 37SessionRequestManager::~SessionRequestManager() = default;
56 38
@@ -69,7 +51,7 @@ bool SessionRequestManager::HasSessionRequestHandler(const HLERequestContext& co
69 } 51 }
70} 52}
71 53
72Result SessionRequestManager::CompleteSyncRequest(KServerSession* server_session, 54Result SessionRequestManager::CompleteSyncRequest(Kernel::KServerSession* server_session,
73 HLERequestContext& context) { 55 HLERequestContext& context) {
74 Result result = ResultSuccess; 56 Result result = ResultSuccess;
75 57
@@ -97,7 +79,7 @@ Result SessionRequestManager::CompleteSyncRequest(KServerSession* server_session
97 return result; 79 return result;
98} 80}
99 81
100Result SessionRequestManager::HandleDomainSyncRequest(KServerSession* server_session, 82Result SessionRequestManager::HandleDomainSyncRequest(Kernel::KServerSession* server_session,
101 HLERequestContext& context) { 83 HLERequestContext& context) {
102 if (!context.HasDomainMessageHeader()) { 84 if (!context.HasDomainMessageHeader()) {
103 return ResultSuccess; 85 return ResultSuccess;
@@ -142,16 +124,17 @@ Result SessionRequestManager::HandleDomainSyncRequest(KServerSession* server_ses
142 return ResultSuccess; 124 return ResultSuccess;
143} 125}
144 126
145HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& memory_, 127HLERequestContext::HLERequestContext(Kernel::KernelCore& kernel_, Core::Memory::Memory& memory_,
146 KServerSession* server_session_, KThread* thread_) 128 Kernel::KServerSession* server_session_,
129 Kernel::KThread* thread_)
147 : server_session(server_session_), thread(thread_), kernel{kernel_}, memory{memory_} { 130 : server_session(server_session_), thread(thread_), kernel{kernel_}, memory{memory_} {
148 cmd_buf[0] = 0; 131 cmd_buf[0] = 0;
149} 132}
150 133
151HLERequestContext::~HLERequestContext() = default; 134HLERequestContext::~HLERequestContext() = default;
152 135
153void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf, 136void HLERequestContext::ParseCommandBuffer(const Kernel::KHandleTable& handle_table,
154 bool incoming) { 137 u32_le* src_cmdbuf, bool incoming) {
155 IPC::RequestParser rp(src_cmdbuf); 138 IPC::RequestParser rp(src_cmdbuf);
156 command_header = rp.PopRaw<IPC::CommandHeader>(); 139 command_header = rp.PopRaw<IPC::CommandHeader>();
157 140
@@ -271,8 +254,8 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32
271 rp.Skip(1, false); // The command is actually an u64, but we don't use the high part. 254 rp.Skip(1, false); // The command is actually an u64, but we don't use the high part.
272} 255}
273 256
274Result HLERequestContext::PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, 257Result HLERequestContext::PopulateFromIncomingCommandBuffer(
275 u32_le* src_cmdbuf) { 258 const Kernel::KHandleTable& handle_table, u32_le* src_cmdbuf) {
276 ParseCommandBuffer(handle_table, src_cmdbuf, true); 259 ParseCommandBuffer(handle_table, src_cmdbuf, true);
277 260
278 if (command_header->IsCloseCommand()) { 261 if (command_header->IsCloseCommand()) {
@@ -285,7 +268,7 @@ Result HLERequestContext::PopulateFromIncomingCommandBuffer(const KHandleTable&
285 return ResultSuccess; 268 return ResultSuccess;
286} 269}
287 270
288Result HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_thread) { 271Result HLERequestContext::WriteToOutgoingCommandBuffer(Kernel::KThread& requesting_thread) {
289 auto current_offset = handles_offset; 272 auto current_offset = handles_offset;
290 auto& owner_process = *requesting_thread.GetOwnerProcess(); 273 auto& owner_process = *requesting_thread.GetOwnerProcess();
291 auto& handle_table = owner_process.GetHandleTable(); 274 auto& handle_table = owner_process.GetHandleTable();
@@ -546,4 +529,4 @@ std::string HLERequestContext::Description() const {
546 return s.str(); 529 return s.str();
547} 530}
548 531
549} // namespace Kernel 532} // namespace Service
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/service/hle_ipc.h
index 5bf4f171b..4bd24c899 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/service/hle_ipc.h
@@ -31,31 +31,22 @@ class ResponseBuilder;
31 31
32namespace Service { 32namespace Service {
33class ServiceFrameworkBase; 33class ServiceFrameworkBase;
34} 34class ServerManager;
35 35} // namespace Service
36enum class ServiceThreadType {
37 Default,
38 CreateNew,
39};
40 36
41namespace Kernel { 37namespace Kernel {
42
43class Domain;
44class HLERequestContext;
45class KAutoObject; 38class KAutoObject;
46class KernelCore; 39class KernelCore;
47class KEvent;
48class KHandleTable; 40class KHandleTable;
49class KServerPort;
50class KProcess;
51class KServerSession; 41class KServerSession;
52class KThread; 42class KThread;
53class KReadableEvent; 43} // namespace Kernel
54class KSession;
55class SessionRequestManager;
56class ServiceThread;
57 44
58enum class ThreadWakeupReason; 45namespace Service {
46
47using Handle = Kernel::Handle;
48
49class HLERequestContext;
59 50
60/** 51/**
61 * Interface implemented by HLE Session handlers. 52 * Interface implemented by HLE Session handlers.
@@ -64,8 +55,7 @@ enum class ThreadWakeupReason;
64 */ 55 */
65class SessionRequestHandler : public std::enable_shared_from_this<SessionRequestHandler> { 56class SessionRequestHandler : public std::enable_shared_from_this<SessionRequestHandler> {
66public: 57public:
67 SessionRequestHandler(KernelCore& kernel_, const char* service_name_, 58 SessionRequestHandler(Kernel::KernelCore& kernel_, const char* service_name_);
68 ServiceThreadType thread_type);
69 virtual ~SessionRequestHandler(); 59 virtual ~SessionRequestHandler();
70 60
71 /** 61 /**
@@ -77,19 +67,10 @@ public:
77 * @returns Result the result code of the translate operation. 67 * @returns Result the result code of the translate operation.
78 */ 68 */
79 virtual Result HandleSyncRequest(Kernel::KServerSession& session, 69 virtual Result HandleSyncRequest(Kernel::KServerSession& session,
80 Kernel::HLERequestContext& context) = 0; 70 HLERequestContext& context) = 0;
81
82 void AcceptSession(KServerPort* server_port);
83 void RegisterSession(KServerSession* server_session,
84 std::shared_ptr<SessionRequestManager> manager);
85
86 ServiceThread& GetServiceThread() const {
87 return service_thread;
88 }
89 71
90protected: 72protected:
91 KernelCore& kernel; 73 Kernel::KernelCore& kernel;
92 ServiceThread& service_thread;
93}; 74};
94 75
95using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>; 76using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>;
@@ -102,7 +83,8 @@ using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;
102 */ 83 */
103class SessionRequestManager final { 84class SessionRequestManager final {
104public: 85public:
105 explicit SessionRequestManager(KernelCore& kernel); 86 explicit SessionRequestManager(Kernel::KernelCore& kernel,
87 Service::ServerManager& server_manager);
106 ~SessionRequestManager(); 88 ~SessionRequestManager();
107 89
108 bool IsDomain() const { 90 bool IsDomain() const {
@@ -155,48 +137,47 @@ public:
155 session_handler = std::move(handler); 137 session_handler = std::move(handler);
156 } 138 }
157 139
158 ServiceThread& GetServiceThread() const { 140 bool HasSessionRequestHandler(const HLERequestContext& context) const;
159 return session_handler->GetServiceThread(); 141
142 Result HandleDomainSyncRequest(Kernel::KServerSession* server_session,
143 HLERequestContext& context);
144 Result CompleteSyncRequest(Kernel::KServerSession* server_session, HLERequestContext& context);
145
146 Service::ServerManager& GetServerManager() {
147 return server_manager;
160 } 148 }
161 149
162 bool HasSessionRequestHandler(const HLERequestContext& context) const; 150 // TODO: remove this when sm: is implemented with the proper IUserInterface
151 // abstraction, creating a new C++ handler object for each session:
152
153 bool GetIsInitializedForSm() const {
154 return is_initialized_for_sm;
155 }
163 156
164 Result HandleDomainSyncRequest(KServerSession* server_session, HLERequestContext& context); 157 void SetIsInitializedForSm() {
165 Result CompleteSyncRequest(KServerSession* server_session, HLERequestContext& context); 158 is_initialized_for_sm = true;
159 }
166 160
167private: 161private:
168 bool convert_to_domain{}; 162 bool convert_to_domain{};
169 bool is_domain{}; 163 bool is_domain{};
164 bool is_initialized_for_sm{};
170 SessionRequestHandlerPtr session_handler; 165 SessionRequestHandlerPtr session_handler;
171 std::vector<SessionRequestHandlerPtr> domain_handlers; 166 std::vector<SessionRequestHandlerPtr> domain_handlers;
172 167
173private: 168private:
174 KernelCore& kernel; 169 Kernel::KernelCore& kernel;
170 Service::ServerManager& server_manager;
175}; 171};
176 172
177/** 173/**
178 * Class containing information about an in-flight IPC request being handled by an HLE service 174 * Class containing information about an in-flight IPC request being handled by an HLE service
179 * implementation. Services should avoid using old global APIs (e.g. Kernel::GetCommandBuffer()) and 175 * implementation.
180 * when possible use the APIs in this class to service the request.
181 *
182 * HLE handle protocol
183 * ===================
184 *
185 * To avoid needing HLE services to keep a separate handle table, or having to directly modify the
186 * requester's table, a tweaked protocol is used to receive and send handles in requests. The kernel
187 * will decode the incoming handles into object pointers and insert a id in the buffer where the
188 * handle would normally be. The service then calls GetIncomingHandle() with that id to get the
189 * pointer to the object. Similarly, instead of inserting a handle into the command buffer, the
190 * service calls AddOutgoingHandle() and stores the returned id where the handle would normally go.
191 *
192 * The end result is similar to just giving services their own real handle tables, but since these
193 * ids are local to a specific context, it avoids requiring services to manage handles for objects
194 * across multiple calls and ensuring that unneeded handles are cleaned up.
195 */ 176 */
196class HLERequestContext { 177class HLERequestContext {
197public: 178public:
198 explicit HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory, 179 explicit HLERequestContext(Kernel::KernelCore& kernel, Core::Memory::Memory& memory,
199 KServerSession* session, KThread* thread); 180 Kernel::KServerSession* session, Kernel::KThread* thread);
200 ~HLERequestContext(); 181 ~HLERequestContext();
201 182
202 /// Returns a pointer to the IPC command buffer for this request. 183 /// Returns a pointer to the IPC command buffer for this request.
@@ -213,10 +194,11 @@ public:
213 } 194 }
214 195
215 /// Populates this context with data from the requesting process/thread. 196 /// Populates this context with data from the requesting process/thread.
216 Result PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf); 197 Result PopulateFromIncomingCommandBuffer(const Kernel::KHandleTable& handle_table,
198 u32_le* src_cmdbuf);
217 199
218 /// Writes data from this context back to the requesting process/thread. 200 /// Writes data from this context back to the requesting process/thread.
219 Result WriteToOutgoingCommandBuffer(KThread& requesting_thread); 201 Result WriteToOutgoingCommandBuffer(Kernel::KThread& requesting_thread);
220 202
221 [[nodiscard]] u32_le GetHipcCommand() const { 203 [[nodiscard]] u32_le GetHipcCommand() const {
222 return command; 204 return command;
@@ -343,11 +325,11 @@ public:
343 return incoming_move_handles.at(index); 325 return incoming_move_handles.at(index);
344 } 326 }
345 327
346 void AddMoveObject(KAutoObject* object) { 328 void AddMoveObject(Kernel::KAutoObject* object) {
347 outgoing_move_objects.emplace_back(object); 329 outgoing_move_objects.emplace_back(object);
348 } 330 }
349 331
350 void AddCopyObject(KAutoObject* object) { 332 void AddCopyObject(Kernel::KAutoObject* object) {
351 outgoing_copy_objects.emplace_back(object); 333 outgoing_copy_objects.emplace_back(object);
352 } 334 }
353 335
@@ -366,7 +348,7 @@ public:
366 348
367 [[nodiscard]] std::string Description() const; 349 [[nodiscard]] std::string Description() const;
368 350
369 [[nodiscard]] KThread& GetThread() { 351 [[nodiscard]] Kernel::KThread& GetThread() {
370 return *thread; 352 return *thread;
371 } 353 }
372 354
@@ -374,20 +356,29 @@ public:
374 return manager.lock(); 356 return manager.lock();
375 } 357 }
376 358
359 bool GetIsDeferred() const {
360 return is_deferred;
361 }
362
363 void SetIsDeferred(bool is_deferred_ = true) {
364 is_deferred = is_deferred_;
365 }
366
377private: 367private:
378 friend class IPC::ResponseBuilder; 368 friend class IPC::ResponseBuilder;
379 369
380 void ParseCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf, bool incoming); 370 void ParseCommandBuffer(const Kernel::KHandleTable& handle_table, u32_le* src_cmdbuf,
371 bool incoming);
381 372
382 std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; 373 std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
383 Kernel::KServerSession* server_session{}; 374 Kernel::KServerSession* server_session{};
384 KThread* thread; 375 Kernel::KThread* thread;
385 376
386 std::vector<Handle> incoming_move_handles; 377 std::vector<Handle> incoming_move_handles;
387 std::vector<Handle> incoming_copy_handles; 378 std::vector<Handle> incoming_copy_handles;
388 379
389 std::vector<KAutoObject*> outgoing_move_objects; 380 std::vector<Kernel::KAutoObject*> outgoing_move_objects;
390 std::vector<KAutoObject*> outgoing_copy_objects; 381 std::vector<Kernel::KAutoObject*> outgoing_copy_objects;
391 std::vector<SessionRequestHandlerPtr> outgoing_domain_objects; 382 std::vector<SessionRequestHandlerPtr> outgoing_domain_objects;
392 383
393 std::optional<IPC::CommandHeader> command_header; 384 std::optional<IPC::CommandHeader> command_header;
@@ -408,9 +399,10 @@ private:
408 u32 domain_offset{}; 399 u32 domain_offset{};
409 400
410 std::weak_ptr<SessionRequestManager> manager{}; 401 std::weak_ptr<SessionRequestManager> manager{};
402 bool is_deferred{false};
411 403
412 KernelCore& kernel; 404 Kernel::KernelCore& kernel;
413 Core::Memory::Memory& memory; 405 Core::Memory::Memory& memory;
414}; 406};
415 407
416} // namespace Kernel 408} // namespace Service
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/service/ipc_helpers.h
index 38d6cfaff..8703b57ca 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/service/ipc_helpers.h
@@ -10,26 +10,27 @@
10#include "common/assert.h" 10#include "common/assert.h"
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/hle/ipc.h" 12#include "core/hle/ipc.h"
13#include "core/hle/kernel/hle_ipc.h"
14#include "core/hle/kernel/k_process.h" 13#include "core/hle/kernel/k_process.h"
15#include "core/hle/kernel/k_resource_limit.h" 14#include "core/hle/kernel/k_resource_limit.h"
16#include "core/hle/kernel/k_session.h" 15#include "core/hle/kernel/k_session.h"
17#include "core/hle/result.h" 16#include "core/hle/result.h"
17#include "core/hle/service/hle_ipc.h"
18#include "core/hle/service/server_manager.h"
18 19
19namespace IPC { 20namespace IPC {
20 21
21constexpr Result ERR_REMOTE_PROCESS_DEAD{ErrorModule::HIPC, 301}; 22constexpr Result ResultSessionClosed{ErrorModule::HIPC, 301};
22 23
23class RequestHelperBase { 24class RequestHelperBase {
24protected: 25protected:
25 Kernel::HLERequestContext* context = nullptr; 26 Service::HLERequestContext* context = nullptr;
26 u32* cmdbuf; 27 u32* cmdbuf;
27 u32 index = 0; 28 u32 index = 0;
28 29
29public: 30public:
30 explicit RequestHelperBase(u32* command_buffer) : cmdbuf(command_buffer) {} 31 explicit RequestHelperBase(u32* command_buffer) : cmdbuf(command_buffer) {}
31 32
32 explicit RequestHelperBase(Kernel::HLERequestContext& ctx) 33 explicit RequestHelperBase(Service::HLERequestContext& ctx)
33 : context(&ctx), cmdbuf(ctx.CommandBuffer()) {} 34 : context(&ctx), cmdbuf(ctx.CommandBuffer()) {}
34 35
35 void Skip(u32 size_in_words, bool set_to_null) { 36 void Skip(u32 size_in_words, bool set_to_null) {
@@ -67,7 +68,7 @@ public:
67 AlwaysMoveHandles = 1, 68 AlwaysMoveHandles = 1,
68 }; 69 };
69 70
70 explicit ResponseBuilder(Kernel::HLERequestContext& ctx, u32 normal_params_size_, 71 explicit ResponseBuilder(Service::HLERequestContext& ctx, u32 normal_params_size_,
71 u32 num_handles_to_copy_ = 0, u32 num_objects_to_move_ = 0, 72 u32 num_handles_to_copy_ = 0, u32 num_objects_to_move_ = 0,
72 Flags flags = Flags::None) 73 Flags flags = Flags::None)
73 : RequestHelperBase(ctx), normal_params_size(normal_params_size_), 74 : RequestHelperBase(ctx), normal_params_size(normal_params_size_),
@@ -145,7 +146,9 @@ public:
145 146
146 template <class T> 147 template <class T>
147 void PushIpcInterface(std::shared_ptr<T> iface) { 148 void PushIpcInterface(std::shared_ptr<T> iface) {
148 if (context->GetManager()->IsDomain()) { 149 auto manager{context->GetManager()};
150
151 if (manager->IsDomain()) {
149 context->AddDomainObject(std::move(iface)); 152 context->AddDomainObject(std::move(iface));
150 } else { 153 } else {
151 kernel.ApplicationProcess()->GetResourceLimit()->Reserve( 154 kernel.ApplicationProcess()->GetResourceLimit()->Reserve(
@@ -153,8 +156,11 @@ public:
153 156
154 auto* session = Kernel::KSession::Create(kernel); 157 auto* session = Kernel::KSession::Create(kernel);
155 session->Initialize(nullptr, iface->GetServiceName()); 158 session->Initialize(nullptr, iface->GetServiceName());
156 iface->RegisterSession(&session->GetServerSession(), 159
157 std::make_shared<Kernel::SessionRequestManager>(kernel)); 160 auto next_manager = std::make_shared<Service::SessionRequestManager>(
161 kernel, manager->GetServerManager());
162 next_manager->SetSessionHandler(iface);
163 manager->GetServerManager().RegisterSession(&session->GetServerSession(), next_manager);
158 164
159 context->AddMoveObject(&session->GetClientSession()); 165 context->AddMoveObject(&session->GetClientSession());
160 } 166 }
@@ -341,7 +347,7 @@ class RequestParser : public RequestHelperBase {
341public: 347public:
342 explicit RequestParser(u32* command_buffer) : RequestHelperBase(command_buffer) {} 348 explicit RequestParser(u32* command_buffer) : RequestHelperBase(command_buffer) {}
343 349
344 explicit RequestParser(Kernel::HLERequestContext& ctx) : RequestHelperBase(ctx) { 350 explicit RequestParser(Service::HLERequestContext& ctx) : RequestHelperBase(ctx) {
345 // TIPC does not have data payload offset 351 // TIPC does not have data payload offset
346 if (!ctx.IsTipc()) { 352 if (!ctx.IsTipc()) {
347 ASSERT_MSG(ctx.GetDataPayloadOffset(), "context is incomplete"); 353 ASSERT_MSG(ctx.GetDataPayloadOffset(), "context is incomplete");
diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp
index 47a1277ea..46bcfd695 100644
--- a/src/core/hle/service/jit/jit.cpp
+++ b/src/core/hle/service/jit/jit.cpp
@@ -3,12 +3,13 @@
3 3
4#include "core/arm/symbols.h" 4#include "core/arm/symbols.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/ipc_helpers.h"
7#include "core/hle/kernel/k_code_memory.h" 6#include "core/hle/kernel/k_code_memory.h"
8#include "core/hle/kernel/k_transfer_memory.h" 7#include "core/hle/kernel/k_transfer_memory.h"
9#include "core/hle/result.h" 8#include "core/hle/result.h"
9#include "core/hle/service/ipc_helpers.h"
10#include "core/hle/service/jit/jit.h" 10#include "core/hle/service/jit/jit.h"
11#include "core/hle/service/jit/jit_context.h" 11#include "core/hle/service/jit/jit_context.h"
12#include "core/hle/service/server_manager.h"
12#include "core/hle/service/service.h" 13#include "core/hle/service/service.h"
13#include "core/memory.h" 14#include "core/memory.h"
14 15
@@ -23,8 +24,8 @@ class IJitEnvironment final : public ServiceFramework<IJitEnvironment> {
23public: 24public:
24 explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx, 25 explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx,
25 CodeRange user_ro) 26 CodeRange user_ro)
26 : ServiceFramework{system_, "IJitEnvironment", ServiceThreadType::CreateNew}, 27 : ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, context{
27 process{&process_}, context{system_.Memory()} { 28 system_.Memory()} {
28 // clang-format off 29 // clang-format off
29 static const FunctionInfo functions[] = { 30 static const FunctionInfo functions[] = {
30 {0, &IJitEnvironment::GenerateCode, "GenerateCode"}, 31 {0, &IJitEnvironment::GenerateCode, "GenerateCode"},
@@ -43,7 +44,7 @@ public:
43 configuration.sys_rx_memory = user_rx; 44 configuration.sys_rx_memory = user_rx;
44 } 45 }
45 46
46 void GenerateCode(Kernel::HLERequestContext& ctx) { 47 void GenerateCode(HLERequestContext& ctx) {
47 LOG_DEBUG(Service_JIT, "called"); 48 LOG_DEBUG(Service_JIT, "called");
48 49
49 struct InputParameters { 50 struct InputParameters {
@@ -125,7 +126,7 @@ public:
125 } 126 }
126 }; 127 };
127 128
128 void Control(Kernel::HLERequestContext& ctx) { 129 void Control(HLERequestContext& ctx) {
129 LOG_DEBUG(Service_JIT, "called"); 130 LOG_DEBUG(Service_JIT, "called");
130 131
131 IPC::RequestParser rp{ctx}; 132 IPC::RequestParser rp{ctx};
@@ -170,7 +171,7 @@ public:
170 } 171 }
171 } 172 }
172 173
173 void LoadPlugin(Kernel::HLERequestContext& ctx) { 174 void LoadPlugin(HLERequestContext& ctx) {
174 LOG_DEBUG(Service_JIT, "called"); 175 LOG_DEBUG(Service_JIT, "called");
175 176
176 IPC::RequestParser rp{ctx}; 177 IPC::RequestParser rp{ctx};
@@ -276,7 +277,7 @@ public:
276 rb.Push(ResultSuccess); 277 rb.Push(ResultSuccess);
277 } 278 }
278 279
279 void GetCodeAddress(Kernel::HLERequestContext& ctx) { 280 void GetCodeAddress(HLERequestContext& ctx) {
280 LOG_DEBUG(Service_JIT, "called"); 281 LOG_DEBUG(Service_JIT, "called");
281 282
282 IPC::ResponseBuilder rb{ctx, 6}; 283 IPC::ResponseBuilder rb{ctx, 6};
@@ -332,7 +333,7 @@ public:
332 RegisterHandlers(functions); 333 RegisterHandlers(functions);
333 } 334 }
334 335
335 void CreateJitEnvironment(Kernel::HLERequestContext& ctx) { 336 void CreateJitEnvironment(HLERequestContext& ctx) {
336 LOG_DEBUG(Service_JIT, "called"); 337 LOG_DEBUG(Service_JIT, "called");
337 338
338 struct Parameters { 339 struct Parameters {
@@ -397,8 +398,11 @@ public:
397 } 398 }
398}; 399};
399 400
400void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 401void LoopProcess(Core::System& system) {
401 std::make_shared<JITU>(system)->InstallAsService(sm); 402 auto server_manager = std::make_unique<ServerManager>(system);
403
404 server_manager->RegisterNamedService("jit:u", std::make_shared<JITU>(system));
405 ServerManager::RunServer(std::move(server_manager));
402} 406}
403 407
404} // namespace Service::JIT 408} // namespace Service::JIT
diff --git a/src/core/hle/service/jit/jit.h b/src/core/hle/service/jit/jit.h
index af0f5b4f3..19014c75a 100644
--- a/src/core/hle/service/jit/jit.h
+++ b/src/core/hle/service/jit/jit.h
@@ -7,13 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::JIT { 10namespace Service::JIT {
15 11
16/// Registers all JIT services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
18 13
19} // namespace Service::JIT 14} // namespace Service::JIT
diff --git a/src/core/hle/service/kernel_helpers.cpp b/src/core/hle/service/kernel_helpers.cpp
index 42991928e..a39ce5212 100644
--- a/src/core/hle/service/kernel_helpers.cpp
+++ b/src/core/hle/service/kernel_helpers.cpp
@@ -15,17 +15,24 @@ namespace Service::KernelHelpers {
15 15
16ServiceContext::ServiceContext(Core::System& system_, std::string name_) 16ServiceContext::ServiceContext(Core::System& system_, std::string name_)
17 : kernel(system_.Kernel()) { 17 : kernel(system_.Kernel()) {
18 if (process = Kernel::GetCurrentProcessPointer(kernel); process != nullptr) {
19 return;
20 }
21
18 // Create the process. 22 // Create the process.
19 process = Kernel::KProcess::Create(kernel); 23 process = Kernel::KProcess::Create(kernel);
20 ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_), 24 ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_),
21 Kernel::KProcess::ProcessType::KernelInternal, 25 Kernel::KProcess::ProcessType::KernelInternal,
22 kernel.GetSystemResourceLimit()) 26 kernel.GetSystemResourceLimit())
23 .IsSuccess()); 27 .IsSuccess());
28 process_created = true;
24} 29}
25 30
26ServiceContext::~ServiceContext() { 31ServiceContext::~ServiceContext() {
27 process->Close(); 32 if (process_created) {
28 process = nullptr; 33 process->Close();
34 process = nullptr;
35 }
29} 36}
30 37
31Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) { 38Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) {
diff --git a/src/core/hle/service/kernel_helpers.h b/src/core/hle/service/kernel_helpers.h
index 6415838e5..eca9aefb5 100644
--- a/src/core/hle/service/kernel_helpers.h
+++ b/src/core/hle/service/kernel_helpers.h
@@ -29,6 +29,7 @@ public:
29private: 29private:
30 Kernel::KernelCore& kernel; 30 Kernel::KernelCore& kernel;
31 Kernel::KProcess* process{}; 31 Kernel::KProcess* process{};
32 bool process_created{false};
32}; 33};
33 34
34} // namespace Service::KernelHelpers 35} // namespace Service::KernelHelpers
diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp
index c8415e0bf..98a79365d 100644
--- a/src/core/hle/service/lbl/lbl.cpp
+++ b/src/core/hle/service/lbl/lbl.cpp
@@ -5,8 +5,9 @@
5#include <memory> 5#include <memory>
6 6
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "core/hle/ipc_helpers.h" 8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/lbl/lbl.h" 9#include "core/hle/service/lbl/lbl.h"
10#include "core/hle/service/server_manager.h"
10#include "core/hle/service/service.h" 11#include "core/hle/service/service.h"
11#include "core/hle/service/sm/sm.h" 12#include "core/hle/service/sm/sm.h"
12 13
@@ -59,7 +60,7 @@ private:
59 On = 1, 60 On = 1,
60 }; 61 };
61 62
62 void SetCurrentBrightnessSetting(Kernel::HLERequestContext& ctx) { 63 void SetCurrentBrightnessSetting(HLERequestContext& ctx) {
63 IPC::RequestParser rp{ctx}; 64 IPC::RequestParser rp{ctx};
64 auto brightness = rp.Pop<float>(); 65 auto brightness = rp.Pop<float>();
65 66
@@ -77,7 +78,7 @@ private:
77 rb.Push(ResultSuccess); 78 rb.Push(ResultSuccess);
78 } 79 }
79 80
80 void GetCurrentBrightnessSetting(Kernel::HLERequestContext& ctx) { 81 void GetCurrentBrightnessSetting(HLERequestContext& ctx) {
81 auto brightness = current_brightness; 82 auto brightness = current_brightness;
82 if (!std::isfinite(brightness)) { 83 if (!std::isfinite(brightness)) {
83 LOG_ERROR(Service_LBL, "Brightness is infinite!"); 84 LOG_ERROR(Service_LBL, "Brightness is infinite!");
@@ -91,7 +92,7 @@ private:
91 rb.Push(brightness); 92 rb.Push(brightness);
92 } 93 }
93 94
94 void SwitchBacklightOn(Kernel::HLERequestContext& ctx) { 95 void SwitchBacklightOn(HLERequestContext& ctx) {
95 IPC::RequestParser rp{ctx}; 96 IPC::RequestParser rp{ctx};
96 const auto fade_time = rp.Pop<u64_le>(); 97 const auto fade_time = rp.Pop<u64_le>();
97 LOG_WARNING(Service_LBL, "(STUBBED) called, fade_time={}", fade_time); 98 LOG_WARNING(Service_LBL, "(STUBBED) called, fade_time={}", fade_time);
@@ -102,7 +103,7 @@ private:
102 rb.Push(ResultSuccess); 103 rb.Push(ResultSuccess);
103 } 104 }
104 105
105 void SwitchBacklightOff(Kernel::HLERequestContext& ctx) { 106 void SwitchBacklightOff(HLERequestContext& ctx) {
106 IPC::RequestParser rp{ctx}; 107 IPC::RequestParser rp{ctx};
107 const auto fade_time = rp.Pop<u64_le>(); 108 const auto fade_time = rp.Pop<u64_le>();
108 LOG_WARNING(Service_LBL, "(STUBBED) called, fade_time={}", fade_time); 109 LOG_WARNING(Service_LBL, "(STUBBED) called, fade_time={}", fade_time);
@@ -113,7 +114,7 @@ private:
113 rb.Push(ResultSuccess); 114 rb.Push(ResultSuccess);
114 } 115 }
115 116
116 void GetBacklightSwitchStatus(Kernel::HLERequestContext& ctx) { 117 void GetBacklightSwitchStatus(HLERequestContext& ctx) {
117 LOG_DEBUG(Service_LBL, "called"); 118 LOG_DEBUG(Service_LBL, "called");
118 119
119 IPC::ResponseBuilder rb{ctx, 3}; 120 IPC::ResponseBuilder rb{ctx, 3};
@@ -122,7 +123,7 @@ private:
122 : BacklightSwitchStatus::Off); 123 : BacklightSwitchStatus::Off);
123 } 124 }
124 125
125 void EnableDimming(Kernel::HLERequestContext& ctx) { 126 void EnableDimming(HLERequestContext& ctx) {
126 LOG_DEBUG(Service_LBL, "called"); 127 LOG_DEBUG(Service_LBL, "called");
127 128
128 dimming = true; 129 dimming = true;
@@ -131,7 +132,7 @@ private:
131 rb.Push(ResultSuccess); 132 rb.Push(ResultSuccess);
132 } 133 }
133 134
134 void DisableDimming(Kernel::HLERequestContext& ctx) { 135 void DisableDimming(HLERequestContext& ctx) {
135 LOG_DEBUG(Service_LBL, "called"); 136 LOG_DEBUG(Service_LBL, "called");
136 137
137 dimming = false; 138 dimming = false;
@@ -140,7 +141,7 @@ private:
140 rb.Push(ResultSuccess); 141 rb.Push(ResultSuccess);
141 } 142 }
142 143
143 void IsDimmingEnabled(Kernel::HLERequestContext& ctx) { 144 void IsDimmingEnabled(HLERequestContext& ctx) {
144 LOG_DEBUG(Service_LBL, "called"); 145 LOG_DEBUG(Service_LBL, "called");
145 146
146 IPC::ResponseBuilder rb{ctx, 3}; 147 IPC::ResponseBuilder rb{ctx, 3};
@@ -148,7 +149,7 @@ private:
148 rb.Push(dimming); 149 rb.Push(dimming);
149 } 150 }
150 151
151 void EnableAutoBrightnessControl(Kernel::HLERequestContext& ctx) { 152 void EnableAutoBrightnessControl(HLERequestContext& ctx) {
152 LOG_DEBUG(Service_LBL, "called"); 153 LOG_DEBUG(Service_LBL, "called");
153 auto_brightness = true; 154 auto_brightness = true;
154 update_instantly = true; 155 update_instantly = true;
@@ -157,7 +158,7 @@ private:
157 rb.Push(ResultSuccess); 158 rb.Push(ResultSuccess);
158 } 159 }
159 160
160 void DisableAutoBrightnessControl(Kernel::HLERequestContext& ctx) { 161 void DisableAutoBrightnessControl(HLERequestContext& ctx) {
161 LOG_DEBUG(Service_LBL, "called"); 162 LOG_DEBUG(Service_LBL, "called");
162 auto_brightness = false; 163 auto_brightness = false;
163 164
@@ -165,7 +166,7 @@ private:
165 rb.Push(ResultSuccess); 166 rb.Push(ResultSuccess);
166 } 167 }
167 168
168 void IsAutoBrightnessControlEnabled(Kernel::HLERequestContext& ctx) { 169 void IsAutoBrightnessControlEnabled(HLERequestContext& ctx) {
169 LOG_DEBUG(Service_LBL, "called"); 170 LOG_DEBUG(Service_LBL, "called");
170 171
171 IPC::ResponseBuilder rb{ctx, 3}; 172 IPC::ResponseBuilder rb{ctx, 3};
@@ -173,7 +174,7 @@ private:
173 rb.Push(auto_brightness); 174 rb.Push(auto_brightness);
174 } 175 }
175 176
176 void SetAmbientLightSensorValue(Kernel::HLERequestContext& ctx) { 177 void SetAmbientLightSensorValue(HLERequestContext& ctx) {
177 IPC::RequestParser rp{ctx}; 178 IPC::RequestParser rp{ctx};
178 const auto light_value = rp.Pop<float>(); 179 const auto light_value = rp.Pop<float>();
179 180
@@ -185,7 +186,7 @@ private:
185 rb.Push(ResultSuccess); 186 rb.Push(ResultSuccess);
186 } 187 }
187 188
188 void GetAmbientLightSensorValue(Kernel::HLERequestContext& ctx) { 189 void GetAmbientLightSensorValue(HLERequestContext& ctx) {
189 LOG_DEBUG(Service_LBL, "called"); 190 LOG_DEBUG(Service_LBL, "called");
190 191
191 IPC::ResponseBuilder rb{ctx, 3}; 192 IPC::ResponseBuilder rb{ctx, 3};
@@ -193,7 +194,7 @@ private:
193 rb.Push(ambient_light_value); 194 rb.Push(ambient_light_value);
194 } 195 }
195 196
196 void SetBrightnessReflectionDelayLevel(Kernel::HLERequestContext& ctx) { 197 void SetBrightnessReflectionDelayLevel(HLERequestContext& ctx) {
197 // This is Intentional, this function does absolutely nothing 198 // This is Intentional, this function does absolutely nothing
198 LOG_DEBUG(Service_LBL, "called"); 199 LOG_DEBUG(Service_LBL, "called");
199 200
@@ -201,7 +202,7 @@ private:
201 rb.Push(ResultSuccess); 202 rb.Push(ResultSuccess);
202 } 203 }
203 204
204 void GetBrightnessReflectionDelayLevel(Kernel::HLERequestContext& ctx) { 205 void GetBrightnessReflectionDelayLevel(HLERequestContext& ctx) {
205 // This is intentional, the function is hard coded to return 0.0f on hardware 206 // This is intentional, the function is hard coded to return 0.0f on hardware
206 LOG_DEBUG(Service_LBL, "called"); 207 LOG_DEBUG(Service_LBL, "called");
207 208
@@ -210,7 +211,7 @@ private:
210 rb.Push(0.0f); 211 rb.Push(0.0f);
211 } 212 }
212 213
213 void SetCurrentBrightnessMapping(Kernel::HLERequestContext& ctx) { 214 void SetCurrentBrightnessMapping(HLERequestContext& ctx) {
214 // This is Intentional, this function does absolutely nothing 215 // This is Intentional, this function does absolutely nothing
215 LOG_DEBUG(Service_LBL, "called"); 216 LOG_DEBUG(Service_LBL, "called");
216 217
@@ -218,7 +219,7 @@ private:
218 rb.Push(ResultSuccess); 219 rb.Push(ResultSuccess);
219 } 220 }
220 221
221 void GetCurrentBrightnessMapping(Kernel::HLERequestContext& ctx) { 222 void GetCurrentBrightnessMapping(HLERequestContext& ctx) {
222 // This is Intentional, this function does absolutely nothing 223 // This is Intentional, this function does absolutely nothing
223 LOG_DEBUG(Service_LBL, "called"); 224 LOG_DEBUG(Service_LBL, "called");
224 225
@@ -227,7 +228,7 @@ private:
227 // This function is suppose to return something but it seems like it doesn't 228 // This function is suppose to return something but it seems like it doesn't
228 } 229 }
229 230
230 void SetCurrentAmbientLightSensorMapping(Kernel::HLERequestContext& ctx) { 231 void SetCurrentAmbientLightSensorMapping(HLERequestContext& ctx) {
231 // This is Intentional, this function does absolutely nothing 232 // This is Intentional, this function does absolutely nothing
232 LOG_DEBUG(Service_LBL, "called"); 233 LOG_DEBUG(Service_LBL, "called");
233 234
@@ -235,7 +236,7 @@ private:
235 rb.Push(ResultSuccess); 236 rb.Push(ResultSuccess);
236 } 237 }
237 238
238 void GetCurrentAmbientLightSensorMapping(Kernel::HLERequestContext& ctx) { 239 void GetCurrentAmbientLightSensorMapping(HLERequestContext& ctx) {
239 // This is Intentional, this function does absolutely nothing 240 // This is Intentional, this function does absolutely nothing
240 LOG_DEBUG(Service_LBL, "called"); 241 LOG_DEBUG(Service_LBL, "called");
241 242
@@ -244,7 +245,7 @@ private:
244 // This function is suppose to return something but it seems like it doesn't 245 // This function is suppose to return something but it seems like it doesn't
245 } 246 }
246 247
247 void IsAmbientLightSensorAvailable(Kernel::HLERequestContext& ctx) { 248 void IsAmbientLightSensorAvailable(HLERequestContext& ctx) {
248 LOG_WARNING(Service_LBL, "(STUBBED) called"); 249 LOG_WARNING(Service_LBL, "(STUBBED) called");
249 IPC::ResponseBuilder rb{ctx, 3}; 250 IPC::ResponseBuilder rb{ctx, 3};
250 rb.Push(ResultSuccess); 251 rb.Push(ResultSuccess);
@@ -252,7 +253,7 @@ private:
252 rb.Push(true); 253 rb.Push(true);
253 } 254 }
254 255
255 void SetCurrentBrightnessSettingForVrMode(Kernel::HLERequestContext& ctx) { 256 void SetCurrentBrightnessSettingForVrMode(HLERequestContext& ctx) {
256 IPC::RequestParser rp{ctx}; 257 IPC::RequestParser rp{ctx};
257 auto brightness = rp.Pop<float>(); 258 auto brightness = rp.Pop<float>();
258 259
@@ -269,7 +270,7 @@ private:
269 rb.Push(ResultSuccess); 270 rb.Push(ResultSuccess);
270 } 271 }
271 272
272 void GetCurrentBrightnessSettingForVrMode(Kernel::HLERequestContext& ctx) { 273 void GetCurrentBrightnessSettingForVrMode(HLERequestContext& ctx) {
273 auto brightness = current_vr_brightness; 274 auto brightness = current_vr_brightness;
274 if (!std::isfinite(brightness)) { 275 if (!std::isfinite(brightness)) {
275 LOG_ERROR(Service_LBL, "Brightness is infinite!"); 276 LOG_ERROR(Service_LBL, "Brightness is infinite!");
@@ -283,7 +284,7 @@ private:
283 rb.Push(brightness); 284 rb.Push(brightness);
284 } 285 }
285 286
286 void EnableVrMode(Kernel::HLERequestContext& ctx) { 287 void EnableVrMode(HLERequestContext& ctx) {
287 LOG_DEBUG(Service_LBL, "called"); 288 LOG_DEBUG(Service_LBL, "called");
288 289
289 IPC::ResponseBuilder rb{ctx, 2}; 290 IPC::ResponseBuilder rb{ctx, 2};
@@ -292,7 +293,7 @@ private:
292 vr_mode_enabled = true; 293 vr_mode_enabled = true;
293 } 294 }
294 295
295 void DisableVrMode(Kernel::HLERequestContext& ctx) { 296 void DisableVrMode(HLERequestContext& ctx) {
296 LOG_DEBUG(Service_LBL, "called"); 297 LOG_DEBUG(Service_LBL, "called");
297 298
298 IPC::ResponseBuilder rb{ctx, 2}; 299 IPC::ResponseBuilder rb{ctx, 2};
@@ -301,7 +302,7 @@ private:
301 vr_mode_enabled = false; 302 vr_mode_enabled = false;
302 } 303 }
303 304
304 void IsVrModeEnabled(Kernel::HLERequestContext& ctx) { 305 void IsVrModeEnabled(HLERequestContext& ctx) {
305 LOG_DEBUG(Service_LBL, "called"); 306 LOG_DEBUG(Service_LBL, "called");
306 307
307 IPC::ResponseBuilder rb{ctx, 3}; 308 IPC::ResponseBuilder rb{ctx, 3};
@@ -319,8 +320,11 @@ private:
319 bool auto_brightness = false; // TODO(ogniK): Move to system settings 320 bool auto_brightness = false; // TODO(ogniK): Move to system settings
320}; 321};
321 322
322void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 323void LoopProcess(Core::System& system) {
323 std::make_shared<LBL>(system)->InstallAsService(sm); 324 auto server_manager = std::make_unique<ServerManager>(system);
325
326 server_manager->RegisterNamedService("lbl", std::make_shared<LBL>(system));
327 ServerManager::RunServer(std::move(server_manager));
324} 328}
325 329
326} // namespace Service::LBL 330} // namespace Service::LBL
diff --git a/src/core/hle/service/lbl/lbl.h b/src/core/hle/service/lbl/lbl.h
index 6484105c2..e47759c01 100644
--- a/src/core/hle/service/lbl/lbl.h
+++ b/src/core/hle/service/lbl/lbl.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::LBL { 10namespace Service::LBL {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::LBL 14} // namespace Service::LBL
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp
index e5099d61f..9d149a7cd 100644
--- a/src/core/hle/service/ldn/ldn.cpp
+++ b/src/core/hle/service/ldn/ldn.cpp
@@ -8,6 +8,7 @@
8#include "core/hle/service/ldn/ldn.h" 8#include "core/hle/service/ldn/ldn.h"
9#include "core/hle/service/ldn/ldn_results.h" 9#include "core/hle/service/ldn/ldn_results.h"
10#include "core/hle/service/ldn/ldn_types.h" 10#include "core/hle/service/ldn/ldn_types.h"
11#include "core/hle/service/server_manager.h"
11#include "core/internal_network/network.h" 12#include "core/internal_network/network.h"
12#include "core/internal_network/network_interface.h" 13#include "core/internal_network/network_interface.h"
13#include "network/network.h" 14#include "network/network.h"
@@ -49,7 +50,7 @@ public:
49 RegisterHandlers(functions); 50 RegisterHandlers(functions);
50 } 51 }
51 52
52 void CreateMonitorService(Kernel::HLERequestContext& ctx) { 53 void CreateMonitorService(HLERequestContext& ctx) {
53 LOG_DEBUG(Service_LDN, "called"); 54 LOG_DEBUG(Service_LDN, "called");
54 55
55 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 56 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -106,7 +107,7 @@ class IUserLocalCommunicationService final
106 : public ServiceFramework<IUserLocalCommunicationService> { 107 : public ServiceFramework<IUserLocalCommunicationService> {
107public: 108public:
108 explicit IUserLocalCommunicationService(Core::System& system_) 109 explicit IUserLocalCommunicationService(Core::System& system_)
109 : ServiceFramework{system_, "IUserLocalCommunicationService", ServiceThreadType::CreateNew}, 110 : ServiceFramework{system_, "IUserLocalCommunicationService"},
110 service_context{system, "IUserLocalCommunicationService"}, 111 service_context{system, "IUserLocalCommunicationService"},
111 room_network{system_.GetRoomNetwork()}, lan_discovery{room_network} { 112 room_network{system_.GetRoomNetwork()}, lan_discovery{room_network} {
112 // clang-format off 113 // clang-format off
@@ -168,7 +169,7 @@ public:
168 state_change_event->Signal(); 169 state_change_event->Signal();
169 } 170 }
170 171
171 void GetState(Kernel::HLERequestContext& ctx) { 172 void GetState(HLERequestContext& ctx) {
172 State state = State::Error; 173 State state = State::Error;
173 174
174 if (is_initialized) { 175 if (is_initialized) {
@@ -180,7 +181,7 @@ public:
180 rb.PushEnum(state); 181 rb.PushEnum(state);
181 } 182 }
182 183
183 void GetNetworkInfo(Kernel::HLERequestContext& ctx) { 184 void GetNetworkInfo(HLERequestContext& ctx) {
184 const auto write_buffer_size = ctx.GetWriteBufferSize(); 185 const auto write_buffer_size = ctx.GetWriteBufferSize();
185 186
186 if (write_buffer_size != sizeof(NetworkInfo)) { 187 if (write_buffer_size != sizeof(NetworkInfo)) {
@@ -204,7 +205,7 @@ public:
204 rb.Push(ResultSuccess); 205 rb.Push(ResultSuccess);
205 } 206 }
206 207
207 void GetIpv4Address(Kernel::HLERequestContext& ctx) { 208 void GetIpv4Address(HLERequestContext& ctx) {
208 const auto network_interface = Network::GetSelectedNetworkInterface(); 209 const auto network_interface = Network::GetSelectedNetworkInterface();
209 210
210 if (!network_interface) { 211 if (!network_interface) {
@@ -233,13 +234,13 @@ public:
233 rb.PushRaw(subnet_mask); 234 rb.PushRaw(subnet_mask);
234 } 235 }
235 236
236 void GetDisconnectReason(Kernel::HLERequestContext& ctx) { 237 void GetDisconnectReason(HLERequestContext& ctx) {
237 IPC::ResponseBuilder rb{ctx, 3}; 238 IPC::ResponseBuilder rb{ctx, 3};
238 rb.Push(ResultSuccess); 239 rb.Push(ResultSuccess);
239 rb.PushEnum(lan_discovery.GetDisconnectReason()); 240 rb.PushEnum(lan_discovery.GetDisconnectReason());
240 } 241 }
241 242
242 void GetSecurityParameter(Kernel::HLERequestContext& ctx) { 243 void GetSecurityParameter(HLERequestContext& ctx) {
243 SecurityParameter security_parameter{}; 244 SecurityParameter security_parameter{};
244 NetworkInfo info{}; 245 NetworkInfo info{};
245 const Result rc = lan_discovery.GetNetworkInfo(info); 246 const Result rc = lan_discovery.GetNetworkInfo(info);
@@ -260,7 +261,7 @@ public:
260 rb.PushRaw<SecurityParameter>(security_parameter); 261 rb.PushRaw<SecurityParameter>(security_parameter);
261 } 262 }
262 263
263 void GetNetworkConfig(Kernel::HLERequestContext& ctx) { 264 void GetNetworkConfig(HLERequestContext& ctx) {
264 NetworkConfig config{}; 265 NetworkConfig config{};
265 NetworkInfo info{}; 266 NetworkInfo info{};
266 const Result rc = lan_discovery.GetNetworkInfo(info); 267 const Result rc = lan_discovery.GetNetworkInfo(info);
@@ -282,7 +283,7 @@ public:
282 rb.PushRaw<NetworkConfig>(config); 283 rb.PushRaw<NetworkConfig>(config);
283 } 284 }
284 285
285 void AttachStateChangeEvent(Kernel::HLERequestContext& ctx) { 286 void AttachStateChangeEvent(HLERequestContext& ctx) {
286 LOG_INFO(Service_LDN, "called"); 287 LOG_INFO(Service_LDN, "called");
287 288
288 IPC::ResponseBuilder rb{ctx, 2, 1}; 289 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -290,7 +291,7 @@ public:
290 rb.PushCopyObjects(state_change_event->GetReadableEvent()); 291 rb.PushCopyObjects(state_change_event->GetReadableEvent());
291 } 292 }
292 293
293 void GetNetworkInfoLatestUpdate(Kernel::HLERequestContext& ctx) { 294 void GetNetworkInfoLatestUpdate(HLERequestContext& ctx) {
294 const std::size_t network_buffer_size = ctx.GetWriteBufferSize(0); 295 const std::size_t network_buffer_size = ctx.GetWriteBufferSize(0);
295 const std::size_t node_buffer_count = ctx.GetWriteBufferNumElements<NodeLatestUpdate>(1); 296 const std::size_t node_buffer_count = ctx.GetWriteBufferNumElements<NodeLatestUpdate>(1);
296 297
@@ -320,15 +321,15 @@ public:
320 rb.Push(ResultSuccess); 321 rb.Push(ResultSuccess);
321 } 322 }
322 323
323 void Scan(Kernel::HLERequestContext& ctx) { 324 void Scan(HLERequestContext& ctx) {
324 ScanImpl(ctx); 325 ScanImpl(ctx);
325 } 326 }
326 327
327 void ScanPrivate(Kernel::HLERequestContext& ctx) { 328 void ScanPrivate(HLERequestContext& ctx) {
328 ScanImpl(ctx, true); 329 ScanImpl(ctx, true);
329 } 330 }
330 331
331 void ScanImpl(Kernel::HLERequestContext& ctx, bool is_private = false) { 332 void ScanImpl(HLERequestContext& ctx, bool is_private = false) {
332 IPC::RequestParser rp{ctx}; 333 IPC::RequestParser rp{ctx};
333 const auto channel{rp.PopEnum<WifiChannel>()}; 334 const auto channel{rp.PopEnum<WifiChannel>()};
334 const auto scan_filter{rp.PopRaw<ScanFilter>()}; 335 const auto scan_filter{rp.PopRaw<ScanFilter>()};
@@ -357,40 +358,40 @@ public:
357 rb.Push<u32>(count); 358 rb.Push<u32>(count);
358 } 359 }
359 360
360 void SetWirelessControllerRestriction(Kernel::HLERequestContext& ctx) { 361 void SetWirelessControllerRestriction(HLERequestContext& ctx) {
361 LOG_WARNING(Service_LDN, "(STUBBED) called"); 362 LOG_WARNING(Service_LDN, "(STUBBED) called");
362 363
363 IPC::ResponseBuilder rb{ctx, 2}; 364 IPC::ResponseBuilder rb{ctx, 2};
364 rb.Push(ResultSuccess); 365 rb.Push(ResultSuccess);
365 } 366 }
366 367
367 void OpenAccessPoint(Kernel::HLERequestContext& ctx) { 368 void OpenAccessPoint(HLERequestContext& ctx) {
368 LOG_INFO(Service_LDN, "called"); 369 LOG_INFO(Service_LDN, "called");
369 370
370 IPC::ResponseBuilder rb{ctx, 2}; 371 IPC::ResponseBuilder rb{ctx, 2};
371 rb.Push(lan_discovery.OpenAccessPoint()); 372 rb.Push(lan_discovery.OpenAccessPoint());
372 } 373 }
373 374
374 void CloseAccessPoint(Kernel::HLERequestContext& ctx) { 375 void CloseAccessPoint(HLERequestContext& ctx) {
375 LOG_INFO(Service_LDN, "called"); 376 LOG_INFO(Service_LDN, "called");
376 377
377 IPC::ResponseBuilder rb{ctx, 2}; 378 IPC::ResponseBuilder rb{ctx, 2};
378 rb.Push(lan_discovery.CloseAccessPoint()); 379 rb.Push(lan_discovery.CloseAccessPoint());
379 } 380 }
380 381
381 void CreateNetwork(Kernel::HLERequestContext& ctx) { 382 void CreateNetwork(HLERequestContext& ctx) {
382 LOG_INFO(Service_LDN, "called"); 383 LOG_INFO(Service_LDN, "called");
383 384
384 CreateNetworkImpl(ctx); 385 CreateNetworkImpl(ctx);
385 } 386 }
386 387
387 void CreateNetworkPrivate(Kernel::HLERequestContext& ctx) { 388 void CreateNetworkPrivate(HLERequestContext& ctx) {
388 LOG_INFO(Service_LDN, "called"); 389 LOG_INFO(Service_LDN, "called");
389 390
390 CreateNetworkImpl(ctx, true); 391 CreateNetworkImpl(ctx, true);
391 } 392 }
392 393
393 void CreateNetworkImpl(Kernel::HLERequestContext& ctx, bool is_private = false) { 394 void CreateNetworkImpl(HLERequestContext& ctx, bool is_private = false) {
394 IPC::RequestParser rp{ctx}; 395 IPC::RequestParser rp{ctx};
395 396
396 const auto security_config{rp.PopRaw<SecurityConfig>()}; 397 const auto security_config{rp.PopRaw<SecurityConfig>()};
@@ -404,49 +405,49 @@ public:
404 rb.Push(lan_discovery.CreateNetwork(security_config, user_config, network_Config)); 405 rb.Push(lan_discovery.CreateNetwork(security_config, user_config, network_Config));
405 } 406 }
406 407
407 void DestroyNetwork(Kernel::HLERequestContext& ctx) { 408 void DestroyNetwork(HLERequestContext& ctx) {
408 LOG_INFO(Service_LDN, "called"); 409 LOG_INFO(Service_LDN, "called");
409 410
410 IPC::ResponseBuilder rb{ctx, 2}; 411 IPC::ResponseBuilder rb{ctx, 2};
411 rb.Push(lan_discovery.DestroyNetwork()); 412 rb.Push(lan_discovery.DestroyNetwork());
412 } 413 }
413 414
414 void SetAdvertiseData(Kernel::HLERequestContext& ctx) { 415 void SetAdvertiseData(HLERequestContext& ctx) {
415 const auto read_buffer = ctx.ReadBuffer(); 416 const auto read_buffer = ctx.ReadBuffer();
416 417
417 IPC::ResponseBuilder rb{ctx, 2}; 418 IPC::ResponseBuilder rb{ctx, 2};
418 rb.Push(lan_discovery.SetAdvertiseData(read_buffer)); 419 rb.Push(lan_discovery.SetAdvertiseData(read_buffer));
419 } 420 }
420 421
421 void SetStationAcceptPolicy(Kernel::HLERequestContext& ctx) { 422 void SetStationAcceptPolicy(HLERequestContext& ctx) {
422 LOG_WARNING(Service_LDN, "(STUBBED) called"); 423 LOG_WARNING(Service_LDN, "(STUBBED) called");
423 424
424 IPC::ResponseBuilder rb{ctx, 2}; 425 IPC::ResponseBuilder rb{ctx, 2};
425 rb.Push(ResultSuccess); 426 rb.Push(ResultSuccess);
426 } 427 }
427 428
428 void AddAcceptFilterEntry(Kernel::HLERequestContext& ctx) { 429 void AddAcceptFilterEntry(HLERequestContext& ctx) {
429 LOG_WARNING(Service_LDN, "(STUBBED) called"); 430 LOG_WARNING(Service_LDN, "(STUBBED) called");
430 431
431 IPC::ResponseBuilder rb{ctx, 2}; 432 IPC::ResponseBuilder rb{ctx, 2};
432 rb.Push(ResultSuccess); 433 rb.Push(ResultSuccess);
433 } 434 }
434 435
435 void OpenStation(Kernel::HLERequestContext& ctx) { 436 void OpenStation(HLERequestContext& ctx) {
436 LOG_INFO(Service_LDN, "called"); 437 LOG_INFO(Service_LDN, "called");
437 438
438 IPC::ResponseBuilder rb{ctx, 2}; 439 IPC::ResponseBuilder rb{ctx, 2};
439 rb.Push(lan_discovery.OpenStation()); 440 rb.Push(lan_discovery.OpenStation());
440 } 441 }
441 442
442 void CloseStation(Kernel::HLERequestContext& ctx) { 443 void CloseStation(HLERequestContext& ctx) {
443 LOG_INFO(Service_LDN, "called"); 444 LOG_INFO(Service_LDN, "called");
444 445
445 IPC::ResponseBuilder rb{ctx, 2}; 446 IPC::ResponseBuilder rb{ctx, 2};
446 rb.Push(lan_discovery.CloseStation()); 447 rb.Push(lan_discovery.CloseStation());
447 } 448 }
448 449
449 void Connect(Kernel::HLERequestContext& ctx) { 450 void Connect(HLERequestContext& ctx) {
450 IPC::RequestParser rp{ctx}; 451 IPC::RequestParser rp{ctx};
451 struct Parameters { 452 struct Parameters {
452 SecurityConfig security_config; 453 SecurityConfig security_config;
@@ -480,14 +481,14 @@ public:
480 static_cast<u16>(parameters.local_communication_version))); 481 static_cast<u16>(parameters.local_communication_version)));
481 } 482 }
482 483
483 void Disconnect(Kernel::HLERequestContext& ctx) { 484 void Disconnect(HLERequestContext& ctx) {
484 LOG_INFO(Service_LDN, "called"); 485 LOG_INFO(Service_LDN, "called");
485 486
486 IPC::ResponseBuilder rb{ctx, 2}; 487 IPC::ResponseBuilder rb{ctx, 2};
487 rb.Push(lan_discovery.Disconnect()); 488 rb.Push(lan_discovery.Disconnect());
488 } 489 }
489 490
490 void Initialize(Kernel::HLERequestContext& ctx) { 491 void Initialize(HLERequestContext& ctx) {
491 const auto rc = InitializeImpl(ctx); 492 const auto rc = InitializeImpl(ctx);
492 if (rc.IsError()) { 493 if (rc.IsError()) {
493 LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw); 494 LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw);
@@ -497,7 +498,7 @@ public:
497 rb.Push(rc); 498 rb.Push(rc);
498 } 499 }
499 500
500 void Finalize(Kernel::HLERequestContext& ctx) { 501 void Finalize(HLERequestContext& ctx) {
501 if (auto room_member = room_network.GetRoomMember().lock()) { 502 if (auto room_member = room_network.GetRoomMember().lock()) {
502 room_member->Unbind(ldn_packet_received); 503 room_member->Unbind(ldn_packet_received);
503 } 504 }
@@ -508,7 +509,7 @@ public:
508 rb.Push(lan_discovery.Finalize()); 509 rb.Push(lan_discovery.Finalize());
509 } 510 }
510 511
511 void Initialize2(Kernel::HLERequestContext& ctx) { 512 void Initialize2(HLERequestContext& ctx) {
512 const auto rc = InitializeImpl(ctx); 513 const auto rc = InitializeImpl(ctx);
513 if (rc.IsError()) { 514 if (rc.IsError()) {
514 LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw); 515 LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw);
@@ -518,7 +519,7 @@ public:
518 rb.Push(rc); 519 rb.Push(rc);
519 } 520 }
520 521
521 Result InitializeImpl(Kernel::HLERequestContext& ctx) { 522 Result InitializeImpl(HLERequestContext& ctx) {
522 const auto network_interface = Network::GetSelectedNetworkInterface(); 523 const auto network_interface = Network::GetSelectedNetworkInterface();
523 if (!network_interface) { 524 if (!network_interface) {
524 LOG_ERROR(Service_LDN, "No network interface is set"); 525 LOG_ERROR(Service_LDN, "No network interface is set");
@@ -561,7 +562,7 @@ public:
561 RegisterHandlers(functions); 562 RegisterHandlers(functions);
562 } 563 }
563 564
564 void CreateSystemLocalCommunicationService(Kernel::HLERequestContext& ctx) { 565 void CreateSystemLocalCommunicationService(HLERequestContext& ctx) {
565 LOG_DEBUG(Service_LDN, "called"); 566 LOG_DEBUG(Service_LDN, "called");
566 567
567 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 568 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -582,7 +583,7 @@ public:
582 RegisterHandlers(functions); 583 RegisterHandlers(functions);
583 } 584 }
584 585
585 void CreateUserLocalCommunicationService(Kernel::HLERequestContext& ctx) { 586 void CreateUserLocalCommunicationService(HLERequestContext& ctx) {
586 LOG_DEBUG(Service_LDN, "called"); 587 LOG_DEBUG(Service_LDN, "called");
587 588
588 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 589 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -646,7 +647,7 @@ public:
646 RegisterHandlers(functions); 647 RegisterHandlers(functions);
647 } 648 }
648 649
649 void Initialize(Kernel::HLERequestContext& ctx) { 650 void Initialize(HLERequestContext& ctx) {
650 LOG_WARNING(Service_LDN, "(STUBBED) called"); 651 LOG_WARNING(Service_LDN, "(STUBBED) called");
651 652
652 IPC::ResponseBuilder rb{ctx, 2}; 653 IPC::ResponseBuilder rb{ctx, 2};
@@ -667,7 +668,7 @@ public:
667 RegisterHandlers(functions); 668 RegisterHandlers(functions);
668 } 669 }
669 670
670 void CreateNetworkervice(Kernel::HLERequestContext& ctx) { 671 void CreateNetworkervice(HLERequestContext& ctx) {
671 IPC::RequestParser rp{ctx}; 672 IPC::RequestParser rp{ctx};
672 const u64 reserved_input = rp.Pop<u64>(); 673 const u64 reserved_input = rp.Pop<u64>();
673 const u32 input = rp.Pop<u32>(); 674 const u32 input = rp.Pop<u32>();
@@ -680,7 +681,7 @@ public:
680 rb.PushIpcInterface<INetworkService>(system); 681 rb.PushIpcInterface<INetworkService>(system);
681 } 682 }
682 683
683 void CreateMonitorService(Kernel::HLERequestContext& ctx) { 684 void CreateMonitorService(HLERequestContext& ctx) {
684 IPC::RequestParser rp{ctx}; 685 IPC::RequestParser rp{ctx};
685 const u64 reserved_input = rp.Pop<u64>(); 686 const u64 reserved_input = rp.Pop<u64>();
686 687
@@ -705,7 +706,7 @@ public:
705 RegisterHandlers(functions); 706 RegisterHandlers(functions);
706 } 707 }
707 708
708 void CreateNetworkervice(Kernel::HLERequestContext& ctx) { 709 void CreateNetworkervice(HLERequestContext& ctx) {
709 IPC::RequestParser rp{ctx}; 710 IPC::RequestParser rp{ctx};
710 const u64 reserved_input = rp.Pop<u64>(); 711 const u64 reserved_input = rp.Pop<u64>();
711 const u32 input = rp.Pop<u32>(); 712 const u32 input = rp.Pop<u32>();
@@ -718,7 +719,7 @@ public:
718 rb.PushIpcInterface<INetworkService>(system); 719 rb.PushIpcInterface<INetworkService>(system);
719 } 720 }
720 721
721 void CreateMonitorService(Kernel::HLERequestContext& ctx) { 722 void CreateMonitorService(HLERequestContext& ctx) {
722 IPC::RequestParser rp{ctx}; 723 IPC::RequestParser rp{ctx};
723 const u64 reserved_input = rp.Pop<u64>(); 724 const u64 reserved_input = rp.Pop<u64>();
724 725
@@ -730,12 +731,15 @@ public:
730 } 731 }
731}; 732};
732 733
733void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 734void LoopProcess(Core::System& system) {
734 std::make_shared<LDNM>(system)->InstallAsService(sm); 735 auto server_manager = std::make_unique<ServerManager>(system);
735 std::make_shared<LDNS>(system)->InstallAsService(sm); 736
736 std::make_shared<LDNU>(system)->InstallAsService(sm); 737 server_manager->RegisterNamedService("ldn:m", std::make_shared<LDNM>(system));
737 std::make_shared<LP2PAPP>(system)->InstallAsService(sm); 738 server_manager->RegisterNamedService("ldn:s", std::make_shared<LDNS>(system));
738 std::make_shared<LP2PSYS>(system)->InstallAsService(sm); 739 server_manager->RegisterNamedService("ldn:u", std::make_shared<LDNU>(system));
740 server_manager->RegisterNamedService("lp2p:app", std::make_shared<LP2PAPP>(system));
741 server_manager->RegisterNamedService("lp2p:sys", std::make_shared<LP2PSYS>(system));
742 ServerManager::RunServer(std::move(server_manager));
739} 743}
740 744
741} // namespace Service::LDN 745} // namespace Service::LDN
diff --git a/src/core/hle/service/ldn/ldn.h b/src/core/hle/service/ldn/ldn.h
index 6afe2ea6f..f4a319168 100644
--- a/src/core/hle/service/ldn/ldn.h
+++ b/src/core/hle/service/ldn/ldn.h
@@ -3,9 +3,9 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/ipc_helpers.h"
7#include "core/hle/kernel/k_event.h" 6#include "core/hle/kernel/k_event.h"
8#include "core/hle/result.h" 7#include "core/hle/result.h"
8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/kernel_helpers.h" 9#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/sm/sm.h" 10#include "core/hle/service/sm/sm.h"
11 11
@@ -13,13 +13,8 @@ namespace Core {
13class System; 13class System;
14} 14}
15 15
16namespace Service::SM {
17class ServiceManager;
18}
19
20namespace Service::LDN { 16namespace Service::LDN {
21 17
22/// Registers all LDN services with the specified service manager. 18void LoopProcess(Core::System& system);
23void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
24 19
25} // namespace Service::LDN 20} // namespace Service::LDN
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 2d4d6fe3e..6de96ed5b 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -9,11 +9,12 @@
9#include "common/hex_util.h" 9#include "common/hex_util.h"
10#include "common/scope_exit.h" 10#include "common/scope_exit.h"
11#include "core/core.h" 11#include "core/core.h"
12#include "core/hle/ipc_helpers.h"
13#include "core/hle/kernel/k_page_table.h" 12#include "core/hle/kernel/k_page_table.h"
14#include "core/hle/kernel/svc_results.h" 13#include "core/hle/kernel/svc_results.h"
15#include "core/hle/kernel/svc_types.h" 14#include "core/hle/kernel/svc_types.h"
15#include "core/hle/service/ipc_helpers.h"
16#include "core/hle/service/ldr/ldr.h" 16#include "core/hle/service/ldr/ldr.h"
17#include "core/hle/service/server_manager.h"
17#include "core/hle/service/service.h" 18#include "core/hle/service/service.h"
18#include "core/loader/nro.h" 19#include "core/loader/nro.h"
19#include "core/memory.h" 20#include "core/memory.h"
@@ -159,8 +160,7 @@ public:
159 160
160class RelocatableObject final : public ServiceFramework<RelocatableObject> { 161class RelocatableObject final : public ServiceFramework<RelocatableObject> {
161public: 162public:
162 explicit RelocatableObject(Core::System& system_) 163 explicit RelocatableObject(Core::System& system_) : ServiceFramework{system_, "ldr:ro"} {
163 : ServiceFramework{system_, "ldr:ro", ServiceThreadType::CreateNew} {
164 // clang-format off 164 // clang-format off
165 static const FunctionInfo functions[] = { 165 static const FunctionInfo functions[] = {
166 {0, &RelocatableObject::LoadModule, "LoadModule"}, 166 {0, &RelocatableObject::LoadModule, "LoadModule"},
@@ -175,7 +175,7 @@ public:
175 RegisterHandlers(functions); 175 RegisterHandlers(functions);
176 } 176 }
177 177
178 void RegisterModuleInfo(Kernel::HLERequestContext& ctx) { 178 void RegisterModuleInfo(HLERequestContext& ctx) {
179 struct Parameters { 179 struct Parameters {
180 u64_le process_id; 180 u64_le process_id;
181 u64_le nrr_address; 181 u64_le nrr_address;
@@ -272,7 +272,7 @@ public:
272 rb.Push(ResultSuccess); 272 rb.Push(ResultSuccess);
273 } 273 }
274 274
275 void UnregisterModuleInfo(Kernel::HLERequestContext& ctx) { 275 void UnregisterModuleInfo(HLERequestContext& ctx) {
276 IPC::RequestParser rp{ctx}; 276 IPC::RequestParser rp{ctx};
277 const auto pid = rp.Pop<u64>(); 277 const auto pid = rp.Pop<u64>();
278 const auto nrr_address = rp.Pop<VAddr>(); 278 const auto nrr_address = rp.Pop<VAddr>();
@@ -446,7 +446,7 @@ public:
446 data_start, bss_end_addr - data_start, Kernel::Svc::MemoryPermission::ReadWrite); 446 data_start, bss_end_addr - data_start, Kernel::Svc::MemoryPermission::ReadWrite);
447 } 447 }
448 448
449 void LoadModule(Kernel::HLERequestContext& ctx) { 449 void LoadModule(HLERequestContext& ctx) {
450 struct Parameters { 450 struct Parameters {
451 u64_le process_id; 451 u64_le process_id;
452 u64_le image_address; 452 u64_le image_address;
@@ -592,7 +592,7 @@ public:
592 return ResultSuccess; 592 return ResultSuccess;
593 } 593 }
594 594
595 void UnloadModule(Kernel::HLERequestContext& ctx) { 595 void UnloadModule(HLERequestContext& ctx) {
596 if (!initialized) { 596 if (!initialized) {
597 LOG_ERROR(Service_LDR, "LDR:RO not initialized before use!"); 597 LOG_ERROR(Service_LDR, "LDR:RO not initialized before use!");
598 IPC::ResponseBuilder rb{ctx, 2}; 598 IPC::ResponseBuilder rb{ctx, 2};
@@ -638,7 +638,7 @@ public:
638 rb.Push(result); 638 rb.Push(result);
639 } 639 }
640 640
641 void Initialize(Kernel::HLERequestContext& ctx) { 641 void Initialize(HLERequestContext& ctx) {
642 LOG_WARNING(Service_LDR, "(STUBBED) called"); 642 LOG_WARNING(Service_LDR, "(STUBBED) called");
643 643
644 initialized = true; 644 initialized = true;
@@ -682,11 +682,15 @@ private:
682 } 682 }
683}; 683};
684 684
685void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 685void LoopProcess(Core::System& system) {
686 std::make_shared<DebugMonitor>(system)->InstallAsService(sm); 686 auto server_manager = std::make_unique<ServerManager>(system);
687 std::make_shared<ProcessManager>(system)->InstallAsService(sm); 687
688 std::make_shared<Shell>(system)->InstallAsService(sm); 688 server_manager->RegisterNamedService("ldr:dmnt", std::make_shared<DebugMonitor>(system));
689 std::make_shared<RelocatableObject>(system)->InstallAsService(sm); 689 server_manager->RegisterNamedService("ldr:pm", std::make_shared<ProcessManager>(system));
690 server_manager->RegisterNamedService("ldr:shel", std::make_shared<Shell>(system));
691 server_manager->RegisterNamedService("ldr:ro", std::make_shared<RelocatableObject>(system));
692
693 ServerManager::RunServer(std::move(server_manager));
690} 694}
691 695
692} // namespace Service::LDR 696} // namespace Service::LDR
diff --git a/src/core/hle/service/ldr/ldr.h b/src/core/hle/service/ldr/ldr.h
index 25ffd8442..c9281dbfb 100644
--- a/src/core/hle/service/ldr/ldr.h
+++ b/src/core/hle/service/ldr/ldr.h
@@ -7,13 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::LDR { 10namespace Service::LDR {
15 11
16/// Registers all LDR services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
18 13
19} // namespace Service::LDR 14} // namespace Service::LDR
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index ef4b54046..20df00233 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -8,8 +8,9 @@
8#include <boost/container_hash/hash.hpp> 8#include <boost/container_hash/hash.hpp>
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/core.h" 10#include "core/core.h"
11#include "core/hle/ipc_helpers.h" 11#include "core/hle/service/ipc_helpers.h"
12#include "core/hle/service/lm/lm.h" 12#include "core/hle/service/lm/lm.h"
13#include "core/hle/service/server_manager.h"
13#include "core/hle/service/service.h" 14#include "core/hle/service/service.h"
14 15
15namespace Service::LM { 16namespace Service::LM {
@@ -92,7 +93,7 @@ public:
92 } 93 }
93 94
94private: 95private:
95 void Log(Kernel::HLERequestContext& ctx) { 96 void Log(HLERequestContext& ctx) {
96 std::size_t offset{}; 97 std::size_t offset{};
97 const auto data = ctx.ReadBuffer(); 98 const auto data = ctx.ReadBuffer();
98 99
@@ -147,7 +148,7 @@ private:
147 } 148 }
148 } 149 }
149 150
150 void SetDestination(Kernel::HLERequestContext& ctx) { 151 void SetDestination(HLERequestContext& ctx) {
151 IPC::RequestParser rp{ctx}; 152 IPC::RequestParser rp{ctx};
152 const auto log_destination = rp.PopEnum<LogDestination>(); 153 const auto log_destination = rp.PopEnum<LogDestination>();
153 154
@@ -342,7 +343,7 @@ public:
342 } 343 }
343 344
344private: 345private:
345 void OpenLogger(Kernel::HLERequestContext& ctx) { 346 void OpenLogger(HLERequestContext& ctx) {
346 LOG_DEBUG(Service_LM, "called"); 347 LOG_DEBUG(Service_LM, "called");
347 348
348 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 349 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -351,8 +352,11 @@ private:
351 } 352 }
352}; 353};
353 354
354void InstallInterfaces(Core::System& system) { 355void LoopProcess(Core::System& system) {
355 std::make_shared<LM>(system)->InstallAsService(system.ServiceManager()); 356 auto server_manager = std::make_unique<ServerManager>(system);
357
358 server_manager->RegisterNamedService("lm", std::make_shared<LM>(system));
359 ServerManager::RunServer(std::move(server_manager));
356} 360}
357 361
358} // namespace Service::LM 362} // namespace Service::LM
diff --git a/src/core/hle/service/lm/lm.h b/src/core/hle/service/lm/lm.h
index 266019c30..0d7c39cbc 100644
--- a/src/core/hle/service/lm/lm.h
+++ b/src/core/hle/service/lm/lm.h
@@ -9,7 +9,6 @@ class System;
9 9
10namespace Service::LM { 10namespace Service::LM {
11 11
12/// Registers all LM services with the specified service manager. 12void LoopProcess(Core::System& system);
13void InstallInterfaces(Core::System& system);
14 13
15} // namespace Service::LM 14} // namespace Service::LM
diff --git a/src/core/hle/service/mig/mig.cpp b/src/core/hle/service/mig/mig.cpp
index b9fe0cecd..082e470ab 100644
--- a/src/core/hle/service/mig/mig.cpp
+++ b/src/core/hle/service/mig/mig.cpp
@@ -4,8 +4,8 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/mig/mig.h" 6#include "core/hle/service/mig/mig.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::Migration { 10namespace Service::Migration {
11 11
@@ -32,8 +32,11 @@ public:
32 } 32 }
33}; 33};
34 34
35void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 35void LoopProcess(Core::System& system) {
36 std::make_shared<MIG_USR>(system)->InstallAsService(sm); 36 auto server_manager = std::make_unique<ServerManager>(system);
37
38 server_manager->RegisterNamedService("mig:user", std::make_shared<MIG_USR>(system));
39 ServerManager::RunServer(std::move(server_manager));
37} 40}
38 41
39} // namespace Service::Migration 42} // namespace Service::Migration
diff --git a/src/core/hle/service/mig/mig.h b/src/core/hle/service/mig/mig.h
index f1641a521..c8ed732a5 100644
--- a/src/core/hle/service/mig/mig.h
+++ b/src/core/hle/service/mig/mig.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::Migration { 10namespace Service::Migration {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::Migration 14} // namespace Service::Migration
diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp
index 390514fdc..5c7adf97d 100644
--- a/src/core/hle/service/mii/mii.cpp
+++ b/src/core/hle/service/mii/mii.cpp
@@ -4,11 +4,11 @@
4#include <memory> 4#include <memory>
5 5
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/hle/ipc_helpers.h" 7#include "core/hle/service/ipc_helpers.h"
8#include "core/hle/service/mii/mii.h" 8#include "core/hle/service/mii/mii.h"
9#include "core/hle/service/mii/mii_manager.h" 9#include "core/hle/service/mii/mii_manager.h"
10#include "core/hle/service/server_manager.h"
10#include "core/hle/service/service.h" 11#include "core/hle/service/service.h"
11#include "core/hle/service/sm/sm.h"
12 12
13namespace Service::Mii { 13namespace Service::Mii {
14 14
@@ -65,7 +65,7 @@ private:
65 return out; 65 return out;
66 } 66 }
67 67
68 void IsUpdated(Kernel::HLERequestContext& ctx) { 68 void IsUpdated(HLERequestContext& ctx) {
69 IPC::RequestParser rp{ctx}; 69 IPC::RequestParser rp{ctx};
70 const auto source_flag{rp.PopRaw<SourceFlag>()}; 70 const auto source_flag{rp.PopRaw<SourceFlag>()};
71 71
@@ -76,7 +76,7 @@ private:
76 rb.Push(manager.CheckAndResetUpdateCounter(source_flag, current_update_counter)); 76 rb.Push(manager.CheckAndResetUpdateCounter(source_flag, current_update_counter));
77 } 77 }
78 78
79 void IsFullDatabase(Kernel::HLERequestContext& ctx) { 79 void IsFullDatabase(HLERequestContext& ctx) {
80 LOG_DEBUG(Service_Mii, "called"); 80 LOG_DEBUG(Service_Mii, "called");
81 81
82 IPC::ResponseBuilder rb{ctx, 3}; 82 IPC::ResponseBuilder rb{ctx, 3};
@@ -84,7 +84,7 @@ private:
84 rb.Push(manager.IsFullDatabase()); 84 rb.Push(manager.IsFullDatabase());
85 } 85 }
86 86
87 void GetCount(Kernel::HLERequestContext& ctx) { 87 void GetCount(HLERequestContext& ctx) {
88 IPC::RequestParser rp{ctx}; 88 IPC::RequestParser rp{ctx};
89 const auto source_flag{rp.PopRaw<SourceFlag>()}; 89 const auto source_flag{rp.PopRaw<SourceFlag>()};
90 90
@@ -95,7 +95,7 @@ private:
95 rb.Push<u32>(manager.GetCount(source_flag)); 95 rb.Push<u32>(manager.GetCount(source_flag));
96 } 96 }
97 97
98 void Get(Kernel::HLERequestContext& ctx) { 98 void Get(HLERequestContext& ctx) {
99 IPC::RequestParser rp{ctx}; 99 IPC::RequestParser rp{ctx};
100 const auto source_flag{rp.PopRaw<SourceFlag>()}; 100 const auto source_flag{rp.PopRaw<SourceFlag>()};
101 101
@@ -117,7 +117,7 @@ private:
117 rb.Push<u32>(static_cast<u32>(result->size())); 117 rb.Push<u32>(static_cast<u32>(result->size()));
118 } 118 }
119 119
120 void Get1(Kernel::HLERequestContext& ctx) { 120 void Get1(HLERequestContext& ctx) {
121 IPC::RequestParser rp{ctx}; 121 IPC::RequestParser rp{ctx};
122 const auto source_flag{rp.PopRaw<SourceFlag>()}; 122 const auto source_flag{rp.PopRaw<SourceFlag>()};
123 123
@@ -142,7 +142,7 @@ private:
142 rb.Push<u32>(static_cast<u32>(result->size())); 142 rb.Push<u32>(static_cast<u32>(result->size()));
143 } 143 }
144 144
145 void UpdateLatest(Kernel::HLERequestContext& ctx) { 145 void UpdateLatest(HLERequestContext& ctx) {
146 IPC::RequestParser rp{ctx}; 146 IPC::RequestParser rp{ctx};
147 const auto info{rp.PopRaw<CharInfo>()}; 147 const auto info{rp.PopRaw<CharInfo>()};
148 const auto source_flag{rp.PopRaw<SourceFlag>()}; 148 const auto source_flag{rp.PopRaw<SourceFlag>()};
@@ -161,7 +161,7 @@ private:
161 rb.PushRaw<CharInfo>(*result); 161 rb.PushRaw<CharInfo>(*result);
162 } 162 }
163 163
164 void BuildRandom(Kernel::HLERequestContext& ctx) { 164 void BuildRandom(HLERequestContext& ctx) {
165 IPC::RequestParser rp{ctx}; 165 IPC::RequestParser rp{ctx};
166 166
167 const auto age{rp.PopRaw<Age>()}; 167 const auto age{rp.PopRaw<Age>()};
@@ -196,7 +196,7 @@ private:
196 rb.PushRaw<CharInfo>(manager.BuildRandom(age, gender, race)); 196 rb.PushRaw<CharInfo>(manager.BuildRandom(age, gender, race));
197 } 197 }
198 198
199 void BuildDefault(Kernel::HLERequestContext& ctx) { 199 void BuildDefault(HLERequestContext& ctx) {
200 IPC::RequestParser rp{ctx}; 200 IPC::RequestParser rp{ctx};
201 const auto index{rp.Pop<u32>()}; 201 const auto index{rp.Pop<u32>()};
202 202
@@ -215,7 +215,7 @@ private:
215 rb.PushRaw<CharInfo>(manager.BuildDefault(index)); 215 rb.PushRaw<CharInfo>(manager.BuildDefault(index));
216 } 216 }
217 217
218 void GetIndex(Kernel::HLERequestContext& ctx) { 218 void GetIndex(HLERequestContext& ctx) {
219 IPC::RequestParser rp{ctx}; 219 IPC::RequestParser rp{ctx};
220 const auto info{rp.PopRaw<CharInfo>()}; 220 const auto info{rp.PopRaw<CharInfo>()};
221 221
@@ -227,7 +227,7 @@ private:
227 rb.Push(index); 227 rb.Push(index);
228 } 228 }
229 229
230 void SetInterfaceVersion(Kernel::HLERequestContext& ctx) { 230 void SetInterfaceVersion(HLERequestContext& ctx) {
231 IPC::RequestParser rp{ctx}; 231 IPC::RequestParser rp{ctx};
232 current_interface_version = rp.PopRaw<u32>(); 232 current_interface_version = rp.PopRaw<u32>();
233 233
@@ -239,7 +239,7 @@ private:
239 rb.Push(ResultSuccess); 239 rb.Push(ResultSuccess);
240 } 240 }
241 241
242 void Convert(Kernel::HLERequestContext& ctx) { 242 void Convert(HLERequestContext& ctx) {
243 IPC::RequestParser rp{ctx}; 243 IPC::RequestParser rp{ctx};
244 244
245 const auto mii_v3{rp.PopRaw<Ver3StoreData>()}; 245 const auto mii_v3{rp.PopRaw<Ver3StoreData>()};
@@ -275,7 +275,7 @@ public:
275 } 275 }
276 276
277private: 277private:
278 void GetDatabaseService(Kernel::HLERequestContext& ctx) { 278 void GetDatabaseService(HLERequestContext& ctx) {
279 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 279 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
280 rb.Push(ResultSuccess); 280 rb.Push(ResultSuccess);
281 rb.PushIpcInterface<IDatabaseService>(system); 281 rb.PushIpcInterface<IDatabaseService>(system);
@@ -310,11 +310,13 @@ public:
310 } 310 }
311}; 311};
312 312
313void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 313void LoopProcess(Core::System& system) {
314 std::make_shared<MiiDBModule>(system, "mii:e")->InstallAsService(sm); 314 auto server_manager = std::make_unique<ServerManager>(system);
315 std::make_shared<MiiDBModule>(system, "mii:u")->InstallAsService(sm);
316 315
317 std::make_shared<MiiImg>(system)->InstallAsService(sm); 316 server_manager->RegisterNamedService("mii:e", std::make_shared<MiiDBModule>(system, "mii:e"));
317 server_manager->RegisterNamedService("mii:u", std::make_shared<MiiDBModule>(system, "mii:u"));
318 server_manager->RegisterNamedService("miiimg", std::make_shared<MiiImg>(system));
319 ServerManager::RunServer(std::move(server_manager));
318} 320}
319 321
320} // namespace Service::Mii 322} // namespace Service::Mii
diff --git a/src/core/hle/service/mii/mii.h b/src/core/hle/service/mii/mii.h
index 009d80d58..ed4e3f62b 100644
--- a/src/core/hle/service/mii/mii.h
+++ b/src/core/hle/service/mii/mii.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::Mii { 10namespace Service::Mii {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::Mii 14} // namespace Service::Mii
diff --git a/src/core/hle/service/mm/mm_u.cpp b/src/core/hle/service/mm/mm_u.cpp
index ba8c0e230..6f43b1968 100644
--- a/src/core/hle/service/mm/mm_u.cpp
+++ b/src/core/hle/service/mm/mm_u.cpp
@@ -2,8 +2,9 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h" 5#include "core/hle/service/ipc_helpers.h"
6#include "core/hle/service/mm/mm_u.h" 6#include "core/hle/service/mm/mm_u.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/sm/sm.h" 8#include "core/hle/service/sm/sm.h"
8 9
9namespace Service::MM { 10namespace Service::MM {
@@ -28,21 +29,21 @@ public:
28 } 29 }
29 30
30private: 31private:
31 void InitializeOld(Kernel::HLERequestContext& ctx) { 32 void InitializeOld(HLERequestContext& ctx) {
32 LOG_WARNING(Service_MM, "(STUBBED) called"); 33 LOG_WARNING(Service_MM, "(STUBBED) called");
33 34
34 IPC::ResponseBuilder rb{ctx, 2}; 35 IPC::ResponseBuilder rb{ctx, 2};
35 rb.Push(ResultSuccess); 36 rb.Push(ResultSuccess);
36 } 37 }
37 38
38 void FinalizeOld(Kernel::HLERequestContext& ctx) { 39 void FinalizeOld(HLERequestContext& ctx) {
39 LOG_WARNING(Service_MM, "(STUBBED) called"); 40 LOG_WARNING(Service_MM, "(STUBBED) called");
40 41
41 IPC::ResponseBuilder rb{ctx, 2}; 42 IPC::ResponseBuilder rb{ctx, 2};
42 rb.Push(ResultSuccess); 43 rb.Push(ResultSuccess);
43 } 44 }
44 45
45 void SetAndWaitOld(Kernel::HLERequestContext& ctx) { 46 void SetAndWaitOld(HLERequestContext& ctx) {
46 IPC::RequestParser rp{ctx}; 47 IPC::RequestParser rp{ctx};
47 min = rp.Pop<u32>(); 48 min = rp.Pop<u32>();
48 max = rp.Pop<u32>(); 49 max = rp.Pop<u32>();
@@ -53,7 +54,7 @@ private:
53 rb.Push(ResultSuccess); 54 rb.Push(ResultSuccess);
54 } 55 }
55 56
56 void GetOld(Kernel::HLERequestContext& ctx) { 57 void GetOld(HLERequestContext& ctx) {
57 LOG_DEBUG(Service_MM, "(STUBBED) called"); 58 LOG_DEBUG(Service_MM, "(STUBBED) called");
58 59
59 IPC::ResponseBuilder rb{ctx, 3}; 60 IPC::ResponseBuilder rb{ctx, 3};
@@ -61,7 +62,7 @@ private:
61 rb.Push(current); 62 rb.Push(current);
62 } 63 }
63 64
64 void Initialize(Kernel::HLERequestContext& ctx) { 65 void Initialize(HLERequestContext& ctx) {
65 LOG_WARNING(Service_MM, "(STUBBED) called"); 66 LOG_WARNING(Service_MM, "(STUBBED) called");
66 67
67 IPC::ResponseBuilder rb{ctx, 3}; 68 IPC::ResponseBuilder rb{ctx, 3};
@@ -69,14 +70,14 @@ private:
69 rb.Push<u32>(id); // Any non zero value 70 rb.Push<u32>(id); // Any non zero value
70 } 71 }
71 72
72 void Finalize(Kernel::HLERequestContext& ctx) { 73 void Finalize(HLERequestContext& ctx) {
73 LOG_WARNING(Service_MM, "(STUBBED) called"); 74 LOG_WARNING(Service_MM, "(STUBBED) called");
74 75
75 IPC::ResponseBuilder rb{ctx, 2}; 76 IPC::ResponseBuilder rb{ctx, 2};
76 rb.Push(ResultSuccess); 77 rb.Push(ResultSuccess);
77 } 78 }
78 79
79 void SetAndWait(Kernel::HLERequestContext& ctx) { 80 void SetAndWait(HLERequestContext& ctx) {
80 IPC::RequestParser rp{ctx}; 81 IPC::RequestParser rp{ctx};
81 u32 input_id = rp.Pop<u32>(); 82 u32 input_id = rp.Pop<u32>();
82 min = rp.Pop<u32>(); 83 min = rp.Pop<u32>();
@@ -89,7 +90,7 @@ private:
89 rb.Push(ResultSuccess); 90 rb.Push(ResultSuccess);
90 } 91 }
91 92
92 void Get(Kernel::HLERequestContext& ctx) { 93 void Get(HLERequestContext& ctx) {
93 LOG_DEBUG(Service_MM, "(STUBBED) called"); 94 LOG_DEBUG(Service_MM, "(STUBBED) called");
94 95
95 IPC::ResponseBuilder rb{ctx, 3}; 96 IPC::ResponseBuilder rb{ctx, 3};
@@ -103,8 +104,11 @@ private:
103 u32 id{1}; 104 u32 id{1};
104}; 105};
105 106
106void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 107void LoopProcess(Core::System& system) {
107 std::make_shared<MM_U>(system)->InstallAsService(service_manager); 108 auto server_manager = std::make_unique<ServerManager>(system);
109
110 server_manager->RegisterNamedService("mm:u", std::make_shared<MM_U>(system));
111 ServerManager::RunServer(std::move(server_manager));
108} 112}
109 113
110} // namespace Service::MM 114} // namespace Service::MM
diff --git a/src/core/hle/service/mm/mm_u.h b/src/core/hle/service/mm/mm_u.h
index b40941e35..43117c9b1 100644
--- a/src/core/hle/service/mm/mm_u.h
+++ b/src/core/hle/service/mm/mm_u.h
@@ -7,13 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::MM { 10namespace Service::MM {
15 11
16/// Registers all MM services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::MM 14} // namespace Service::MM
diff --git a/src/core/hle/service/mnpp/mnpp_app.cpp b/src/core/hle/service/mnpp/mnpp_app.cpp
index c3aad5714..b11a92056 100644
--- a/src/core/hle/service/mnpp/mnpp_app.cpp
+++ b/src/core/hle/service/mnpp/mnpp_app.cpp
@@ -2,9 +2,10 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h" 5#include "core/hle/service/ipc_helpers.h"
6#include "core/hle/service/mnpp/mnpp_app.h" 6#include "core/hle/service/mnpp/mnpp_app.h"
7#include "core/hle/service/sm/sm.h" 7#include "core/hle/service/server_manager.h"
8#include "core/hle/service/service.h"
8 9
9namespace Service::MNPP { 10namespace Service::MNPP {
10 11
@@ -22,14 +23,14 @@ public:
22 } 23 }
23 24
24private: 25private:
25 void Unknown0(Kernel::HLERequestContext& ctx) { 26 void Unknown0(HLERequestContext& ctx) {
26 LOG_WARNING(Service_MNPP, "(STUBBED) called"); 27 LOG_WARNING(Service_MNPP, "(STUBBED) called");
27 28
28 IPC::ResponseBuilder rb{ctx, 2}; 29 IPC::ResponseBuilder rb{ctx, 2};
29 rb.Push(ResultSuccess); 30 rb.Push(ResultSuccess);
30 } 31 }
31 32
32 void Unknown1(Kernel::HLERequestContext& ctx) { 33 void Unknown1(HLERequestContext& ctx) {
33 LOG_WARNING(Service_MNPP, "(STUBBED) called"); 34 LOG_WARNING(Service_MNPP, "(STUBBED) called");
34 35
35 IPC::ResponseBuilder rb{ctx, 2}; 36 IPC::ResponseBuilder rb{ctx, 2};
@@ -37,8 +38,11 @@ private:
37 } 38 }
38}; 39};
39 40
40void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 41void LoopProcess(Core::System& system) {
41 std::make_shared<MNPP_APP>(system)->InstallAsService(service_manager); 42 auto server_manager = std::make_unique<ServerManager>(system);
43
44 server_manager->RegisterNamedService("mnpp:app", std::make_shared<MNPP_APP>(system));
45 ServerManager::RunServer(std::move(server_manager));
42} 46}
43 47
44} // namespace Service::MNPP 48} // namespace Service::MNPP
diff --git a/src/core/hle/service/mnpp/mnpp_app.h b/src/core/hle/service/mnpp/mnpp_app.h
index eec75fe0e..40d0395bd 100644
--- a/src/core/hle/service/mnpp/mnpp_app.h
+++ b/src/core/hle/service/mnpp/mnpp_app.h
@@ -7,13 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::MNPP { 10namespace Service::MNPP {
15 11
16/// Registers all MNPP services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::MNPP 14} // namespace Service::MNPP
diff --git a/src/core/hle/service/mutex.cpp b/src/core/hle/service/mutex.cpp
new file mode 100644
index 000000000..07589a0f0
--- /dev/null
+++ b/src/core/hle/service/mutex.cpp
@@ -0,0 +1,43 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/core.h"
5#include "core/hle/kernel/k_event.h"
6#include "core/hle/kernel/k_synchronization_object.h"
7#include "core/hle/service/mutex.h"
8
9namespace Service {
10
11Mutex::Mutex(Core::System& system) : m_system(system) {
12 m_event = Kernel::KEvent::Create(system.Kernel());
13 m_event->Initialize(nullptr);
14
15 ASSERT(R_SUCCEEDED(m_event->Signal()));
16}
17
18Mutex::~Mutex() {
19 m_event->GetReadableEvent().Close();
20 m_event->Close();
21}
22
23void Mutex::lock() {
24 // Infinitely retry until we successfully clear the event.
25 while (R_FAILED(m_event->GetReadableEvent().Reset())) {
26 s32 index;
27 Kernel::KSynchronizationObject* obj = &m_event->GetReadableEvent();
28
29 // The event was already cleared!
30 // Wait for it to become signaled again.
31 ASSERT(R_SUCCEEDED(
32 Kernel::KSynchronizationObject::Wait(m_system.Kernel(), &index, &obj, 1, -1)));
33 }
34
35 // We successfully cleared the event, and now have exclusive ownership.
36}
37
38void Mutex::unlock() {
39 // Unlock.
40 ASSERT(R_SUCCEEDED(m_event->Signal()));
41}
42
43} // namespace Service
diff --git a/src/core/hle/service/mutex.h b/src/core/hle/service/mutex.h
new file mode 100644
index 000000000..95ac9b117
--- /dev/null
+++ b/src/core/hle/service/mutex.h
@@ -0,0 +1,31 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "common/common_types.h"
7
8namespace Core {
9class System;
10}
11
12namespace Kernel {
13class KEvent;
14}
15
16namespace Service {
17
18class Mutex {
19public:
20 explicit Mutex(Core::System& system);
21 ~Mutex();
22
23 void lock();
24 void unlock();
25
26private:
27 Core::System& m_system;
28 Kernel::KEvent* m_event{};
29};
30
31} // namespace Service
diff --git a/src/core/hle/service/ncm/ncm.cpp b/src/core/hle/service/ncm/ncm.cpp
index 4c66cfeba..650666d6b 100644
--- a/src/core/hle/service/ncm/ncm.cpp
+++ b/src/core/hle/service/ncm/ncm.cpp
@@ -4,10 +4,10 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/file_sys/romfs_factory.h" 6#include "core/file_sys/romfs_factory.h"
7#include "core/hle/ipc_helpers.h" 7#include "core/hle/service/ipc_helpers.h"
8#include "core/hle/service/ncm/ncm.h" 8#include "core/hle/service/ncm/ncm.h"
9#include "core/hle/service/server_manager.h"
9#include "core/hle/service/service.h" 10#include "core/hle/service/service.h"
10#include "core/hle/service/sm/sm.h"
11 11
12namespace Service::NCM { 12namespace Service::NCM {
13 13
@@ -132,9 +132,12 @@ public:
132 } 132 }
133}; 133};
134 134
135void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 135void LoopProcess(Core::System& system) {
136 std::make_shared<LR>(system)->InstallAsService(sm); 136 auto server_manager = std::make_unique<ServerManager>(system);
137 std::make_shared<NCM>(system)->InstallAsService(sm); 137
138 server_manager->RegisterNamedService("lr", std::make_shared<LR>(system));
139 server_manager->RegisterNamedService("ncm", std::make_shared<NCM>(system));
140 ServerManager::RunServer(std::move(server_manager));
138} 141}
139 142
140} // namespace Service::NCM 143} // namespace Service::NCM
diff --git a/src/core/hle/service/ncm/ncm.h b/src/core/hle/service/ncm/ncm.h
index de3971437..b78efdcd7 100644
--- a/src/core/hle/service/ncm/ncm.h
+++ b/src/core/hle/service/ncm/ncm.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::NCM { 10namespace Service::NCM {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::NCM 14} // namespace Service::NCM
diff --git a/src/core/hle/service/nfc/mifare_user.cpp b/src/core/hle/service/nfc/mifare_user.cpp
index 51523a3ae..e0bbd46e1 100644
--- a/src/core/hle/service/nfc/mifare_user.cpp
+++ b/src/core/hle/service/nfc/mifare_user.cpp
@@ -4,8 +4,8 @@
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hid/hid_types.h" 6#include "core/hid/hid_types.h"
7#include "core/hle/ipc_helpers.h"
8#include "core/hle/kernel/k_event.h" 7#include "core/hle/kernel/k_event.h"
8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/nfc/mifare_user.h" 9#include "core/hle/service/nfc/mifare_user.h"
10#include "core/hle/service/nfc/nfc_device.h" 10#include "core/hle/service/nfc/nfc_device.h"
11#include "core/hle/service/nfc/nfc_result.h" 11#include "core/hle/service/nfc/nfc_result.h"
@@ -45,7 +45,7 @@ MFIUser ::~MFIUser() {
45 availability_change_event->Close(); 45 availability_change_event->Close();
46} 46}
47 47
48void MFIUser::Initialize(Kernel::HLERequestContext& ctx) { 48void MFIUser::Initialize(HLERequestContext& ctx) {
49 LOG_INFO(Service_NFC, "called"); 49 LOG_INFO(Service_NFC, "called");
50 50
51 state = State::Initialized; 51 state = State::Initialized;
@@ -58,7 +58,7 @@ void MFIUser::Initialize(Kernel::HLERequestContext& ctx) {
58 rb.Push(ResultSuccess); 58 rb.Push(ResultSuccess);
59} 59}
60 60
61void MFIUser::Finalize(Kernel::HLERequestContext& ctx) { 61void MFIUser::Finalize(HLERequestContext& ctx) {
62 LOG_INFO(Service_NFC, "called"); 62 LOG_INFO(Service_NFC, "called");
63 63
64 state = State::NonInitialized; 64 state = State::NonInitialized;
@@ -71,7 +71,7 @@ void MFIUser::Finalize(Kernel::HLERequestContext& ctx) {
71 rb.Push(ResultSuccess); 71 rb.Push(ResultSuccess);
72} 72}
73 73
74void MFIUser::ListDevices(Kernel::HLERequestContext& ctx) { 74void MFIUser::ListDevices(HLERequestContext& ctx) {
75 LOG_DEBUG(Service_NFC, "called"); 75 LOG_DEBUG(Service_NFC, "called");
76 76
77 if (state == State::NonInitialized) { 77 if (state == State::NonInitialized) {
@@ -117,7 +117,7 @@ void MFIUser::ListDevices(Kernel::HLERequestContext& ctx) {
117 rb.Push(static_cast<s32>(nfp_devices.size())); 117 rb.Push(static_cast<s32>(nfp_devices.size()));
118} 118}
119 119
120void MFIUser::StartDetection(Kernel::HLERequestContext& ctx) { 120void MFIUser::StartDetection(HLERequestContext& ctx) {
121 IPC::RequestParser rp{ctx}; 121 IPC::RequestParser rp{ctx};
122 const auto device_handle{rp.Pop<u64>()}; 122 const auto device_handle{rp.Pop<u64>()};
123 LOG_INFO(Service_NFC, "called, device_handle={}", device_handle); 123 LOG_INFO(Service_NFC, "called, device_handle={}", device_handle);
@@ -141,7 +141,7 @@ void MFIUser::StartDetection(Kernel::HLERequestContext& ctx) {
141 rb.Push(result); 141 rb.Push(result);
142} 142}
143 143
144void MFIUser::StopDetection(Kernel::HLERequestContext& ctx) { 144void MFIUser::StopDetection(HLERequestContext& ctx) {
145 IPC::RequestParser rp{ctx}; 145 IPC::RequestParser rp{ctx};
146 const auto device_handle{rp.Pop<u64>()}; 146 const auto device_handle{rp.Pop<u64>()};
147 LOG_INFO(Service_NFC, "called, device_handle={}", device_handle); 147 LOG_INFO(Service_NFC, "called, device_handle={}", device_handle);
@@ -165,7 +165,7 @@ void MFIUser::StopDetection(Kernel::HLERequestContext& ctx) {
165 rb.Push(result); 165 rb.Push(result);
166} 166}
167 167
168void MFIUser::Read(Kernel::HLERequestContext& ctx) { 168void MFIUser::Read(HLERequestContext& ctx) {
169 IPC::RequestParser rp{ctx}; 169 IPC::RequestParser rp{ctx};
170 const auto device_handle{rp.Pop<u64>()}; 170 const auto device_handle{rp.Pop<u64>()};
171 const auto buffer{ctx.ReadBuffer()}; 171 const auto buffer{ctx.ReadBuffer()};
@@ -206,7 +206,7 @@ void MFIUser::Read(Kernel::HLERequestContext& ctx) {
206 rb.Push(result); 206 rb.Push(result);
207} 207}
208 208
209void MFIUser::Write(Kernel::HLERequestContext& ctx) { 209void MFIUser::Write(HLERequestContext& ctx) {
210 IPC::RequestParser rp{ctx}; 210 IPC::RequestParser rp{ctx};
211 const auto device_handle{rp.Pop<u64>()}; 211 const auto device_handle{rp.Pop<u64>()};
212 const auto buffer{ctx.ReadBuffer()}; 212 const auto buffer{ctx.ReadBuffer()};
@@ -250,7 +250,7 @@ void MFIUser::Write(Kernel::HLERequestContext& ctx) {
250 rb.Push(result); 250 rb.Push(result);
251} 251}
252 252
253void MFIUser::GetTagInfo(Kernel::HLERequestContext& ctx) { 253void MFIUser::GetTagInfo(HLERequestContext& ctx) {
254 IPC::RequestParser rp{ctx}; 254 IPC::RequestParser rp{ctx};
255 const auto device_handle{rp.Pop<u64>()}; 255 const auto device_handle{rp.Pop<u64>()};
256 LOG_INFO(Service_NFC, "called, device_handle={}", device_handle); 256 LOG_INFO(Service_NFC, "called, device_handle={}", device_handle);
@@ -276,7 +276,7 @@ void MFIUser::GetTagInfo(Kernel::HLERequestContext& ctx) {
276 rb.Push(result); 276 rb.Push(result);
277} 277}
278 278
279void MFIUser::GetActivateEventHandle(Kernel::HLERequestContext& ctx) { 279void MFIUser::GetActivateEventHandle(HLERequestContext& ctx) {
280 IPC::RequestParser rp{ctx}; 280 IPC::RequestParser rp{ctx};
281 const auto device_handle{rp.Pop<u64>()}; 281 const auto device_handle{rp.Pop<u64>()};
282 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 282 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
@@ -300,7 +300,7 @@ void MFIUser::GetActivateEventHandle(Kernel::HLERequestContext& ctx) {
300 rb.PushCopyObjects(device.value()->GetActivateEvent()); 300 rb.PushCopyObjects(device.value()->GetActivateEvent());
301} 301}
302 302
303void MFIUser::GetDeactivateEventHandle(Kernel::HLERequestContext& ctx) { 303void MFIUser::GetDeactivateEventHandle(HLERequestContext& ctx) {
304 IPC::RequestParser rp{ctx}; 304 IPC::RequestParser rp{ctx};
305 const auto device_handle{rp.Pop<u64>()}; 305 const auto device_handle{rp.Pop<u64>()};
306 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 306 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
@@ -324,7 +324,7 @@ void MFIUser::GetDeactivateEventHandle(Kernel::HLERequestContext& ctx) {
324 rb.PushCopyObjects(device.value()->GetDeactivateEvent()); 324 rb.PushCopyObjects(device.value()->GetDeactivateEvent());
325} 325}
326 326
327void MFIUser::GetState(Kernel::HLERequestContext& ctx) { 327void MFIUser::GetState(HLERequestContext& ctx) {
328 LOG_DEBUG(Service_NFC, "called"); 328 LOG_DEBUG(Service_NFC, "called");
329 329
330 IPC::ResponseBuilder rb{ctx, 3}; 330 IPC::ResponseBuilder rb{ctx, 3};
@@ -332,7 +332,7 @@ void MFIUser::GetState(Kernel::HLERequestContext& ctx) {
332 rb.PushEnum(state); 332 rb.PushEnum(state);
333} 333}
334 334
335void MFIUser::GetDeviceState(Kernel::HLERequestContext& ctx) { 335void MFIUser::GetDeviceState(HLERequestContext& ctx) {
336 IPC::RequestParser rp{ctx}; 336 IPC::RequestParser rp{ctx};
337 const auto device_handle{rp.Pop<u64>()}; 337 const auto device_handle{rp.Pop<u64>()};
338 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 338 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
@@ -350,7 +350,7 @@ void MFIUser::GetDeviceState(Kernel::HLERequestContext& ctx) {
350 rb.PushEnum(device.value()->GetCurrentState()); 350 rb.PushEnum(device.value()->GetCurrentState());
351} 351}
352 352
353void MFIUser::GetNpadId(Kernel::HLERequestContext& ctx) { 353void MFIUser::GetNpadId(HLERequestContext& ctx) {
354 IPC::RequestParser rp{ctx}; 354 IPC::RequestParser rp{ctx};
355 const auto device_handle{rp.Pop<u64>()}; 355 const auto device_handle{rp.Pop<u64>()};
356 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 356 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
@@ -374,7 +374,7 @@ void MFIUser::GetNpadId(Kernel::HLERequestContext& ctx) {
374 rb.PushEnum(device.value()->GetNpadId()); 374 rb.PushEnum(device.value()->GetNpadId());
375} 375}
376 376
377void MFIUser::GetAvailabilityChangeEventHandle(Kernel::HLERequestContext& ctx) { 377void MFIUser::GetAvailabilityChangeEventHandle(HLERequestContext& ctx) {
378 LOG_INFO(Service_NFC, "called"); 378 LOG_INFO(Service_NFC, "called");
379 379
380 if (state == State::NonInitialized) { 380 if (state == State::NonInitialized) {
diff --git a/src/core/hle/service/nfc/mifare_user.h b/src/core/hle/service/nfc/mifare_user.h
index 0e0638cb6..9701f1d7f 100644
--- a/src/core/hle/service/nfc/mifare_user.h
+++ b/src/core/hle/service/nfc/mifare_user.h
@@ -24,20 +24,20 @@ private:
24 Initialized, 24 Initialized,
25 }; 25 };
26 26
27 void Initialize(Kernel::HLERequestContext& ctx); 27 void Initialize(HLERequestContext& ctx);
28 void Finalize(Kernel::HLERequestContext& ctx); 28 void Finalize(HLERequestContext& ctx);
29 void ListDevices(Kernel::HLERequestContext& ctx); 29 void ListDevices(HLERequestContext& ctx);
30 void StartDetection(Kernel::HLERequestContext& ctx); 30 void StartDetection(HLERequestContext& ctx);
31 void StopDetection(Kernel::HLERequestContext& ctx); 31 void StopDetection(HLERequestContext& ctx);
32 void Read(Kernel::HLERequestContext& ctx); 32 void Read(HLERequestContext& ctx);
33 void Write(Kernel::HLERequestContext& ctx); 33 void Write(HLERequestContext& ctx);
34 void GetTagInfo(Kernel::HLERequestContext& ctx); 34 void GetTagInfo(HLERequestContext& ctx);
35 void GetActivateEventHandle(Kernel::HLERequestContext& ctx); 35 void GetActivateEventHandle(HLERequestContext& ctx);
36 void GetDeactivateEventHandle(Kernel::HLERequestContext& ctx); 36 void GetDeactivateEventHandle(HLERequestContext& ctx);
37 void GetState(Kernel::HLERequestContext& ctx); 37 void GetState(HLERequestContext& ctx);
38 void GetDeviceState(Kernel::HLERequestContext& ctx); 38 void GetDeviceState(HLERequestContext& ctx);
39 void GetNpadId(Kernel::HLERequestContext& ctx); 39 void GetNpadId(HLERequestContext& ctx);
40 void GetAvailabilityChangeEventHandle(Kernel::HLERequestContext& ctx); 40 void GetAvailabilityChangeEventHandle(HLERequestContext& ctx);
41 41
42 std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle); 42 std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle);
43 43
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp
index b17b18ab9..6595e34ed 100644
--- a/src/core/hle/service/nfc/nfc.cpp
+++ b/src/core/hle/service/nfc/nfc.cpp
@@ -5,12 +5,12 @@
5 5
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "common/settings.h" 7#include "common/settings.h"
8#include "core/hle/ipc_helpers.h" 8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/nfc/mifare_user.h" 9#include "core/hle/service/nfc/mifare_user.h"
10#include "core/hle/service/nfc/nfc.h" 10#include "core/hle/service/nfc/nfc.h"
11#include "core/hle/service/nfc/nfc_user.h" 11#include "core/hle/service/nfc/nfc_user.h"
12#include "core/hle/service/server_manager.h"
12#include "core/hle/service/service.h" 13#include "core/hle/service/service.h"
13#include "core/hle/service/sm/sm.h"
14 14
15namespace Service::NFC { 15namespace Service::NFC {
16 16
@@ -42,7 +42,7 @@ public:
42 } 42 }
43 43
44private: 44private:
45 void CreateAmInterface(Kernel::HLERequestContext& ctx) { 45 void CreateAmInterface(HLERequestContext& ctx) {
46 LOG_DEBUG(Service_NFC, "called"); 46 LOG_DEBUG(Service_NFC, "called");
47 47
48 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 48 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -64,7 +64,7 @@ public:
64 } 64 }
65 65
66private: 66private:
67 void CreateUserInterface(Kernel::HLERequestContext& ctx) { 67 void CreateUserInterface(HLERequestContext& ctx) {
68 LOG_DEBUG(Service_NFC, "called"); 68 LOG_DEBUG(Service_NFC, "called");
69 69
70 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 70 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -86,7 +86,7 @@ public:
86 } 86 }
87 87
88private: 88private:
89 void CreateUserInterface(Kernel::HLERequestContext& ctx) { 89 void CreateUserInterface(HLERequestContext& ctx) {
90 LOG_DEBUG(Service_NFC, "called"); 90 LOG_DEBUG(Service_NFC, "called");
91 91
92 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 92 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -145,7 +145,7 @@ public:
145 } 145 }
146 146
147private: 147private:
148 void CreateSystemInterface(Kernel::HLERequestContext& ctx) { 148 void CreateSystemInterface(HLERequestContext& ctx) {
149 LOG_DEBUG(Service_NFC, "called"); 149 LOG_DEBUG(Service_NFC, "called");
150 150
151 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 151 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -154,11 +154,14 @@ private:
154 } 154 }
155}; 155};
156 156
157void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 157void LoopProcess(Core::System& system) {
158 std::make_shared<NFC_AM>(system)->InstallAsService(sm); 158 auto server_manager = std::make_unique<ServerManager>(system);
159 std::make_shared<NFC_MF_U>(system)->InstallAsService(sm); 159
160 std::make_shared<NFC_U>(system)->InstallAsService(sm); 160 server_manager->RegisterNamedService("nfc:am", std::make_shared<NFC_AM>(system));
161 std::make_shared<NFC_SYS>(system)->InstallAsService(sm); 161 server_manager->RegisterNamedService("nfc:mf:u", std::make_shared<NFC_MF_U>(system));
162 server_manager->RegisterNamedService("nfc:user", std::make_shared<NFC_U>(system));
163 server_manager->RegisterNamedService("nfc:sys", std::make_shared<NFC_SYS>(system));
164 ServerManager::RunServer(std::move(server_manager));
162} 165}
163 166
164} // namespace Service::NFC 167} // namespace Service::NFC
diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h
index 0107b696c..d15955b75 100644
--- a/src/core/hle/service/nfc/nfc.h
+++ b/src/core/hle/service/nfc/nfc.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::NFC { 10namespace Service::NFC {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::NFC 14} // namespace Service::NFC
diff --git a/src/core/hle/service/nfc/nfc_device.cpp b/src/core/hle/service/nfc/nfc_device.cpp
index 9a3234e8c..3f17d0c7a 100644
--- a/src/core/hle/service/nfc/nfc_device.cpp
+++ b/src/core/hle/service/nfc/nfc_device.cpp
@@ -7,8 +7,8 @@
7#include "core/hid/emulated_controller.h" 7#include "core/hid/emulated_controller.h"
8#include "core/hid/hid_core.h" 8#include "core/hid/hid_core.h"
9#include "core/hid/hid_types.h" 9#include "core/hid/hid_types.h"
10#include "core/hle/ipc_helpers.h"
11#include "core/hle/kernel/k_event.h" 10#include "core/hle/kernel/k_event.h"
11#include "core/hle/service/ipc_helpers.h"
12#include "core/hle/service/nfc/nfc_device.h" 12#include "core/hle/service/nfc/nfc_device.h"
13#include "core/hle/service/nfc/nfc_result.h" 13#include "core/hle/service/nfc/nfc_result.h"
14#include "core/hle/service/nfc/nfc_user.h" 14#include "core/hle/service/nfc/nfc_user.h"
diff --git a/src/core/hle/service/nfc/nfc_user.cpp b/src/core/hle/service/nfc/nfc_user.cpp
index 89aa6b3f5..7c162a4f3 100644
--- a/src/core/hle/service/nfc/nfc_user.cpp
+++ b/src/core/hle/service/nfc/nfc_user.cpp
@@ -4,8 +4,8 @@
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hid/hid_types.h" 6#include "core/hid/hid_types.h"
7#include "core/hle/ipc_helpers.h"
8#include "core/hle/kernel/k_event.h" 7#include "core/hle/kernel/k_event.h"
8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/nfc/nfc_device.h" 9#include "core/hle/service/nfc/nfc_device.h"
10#include "core/hle/service/nfc/nfc_result.h" 10#include "core/hle/service/nfc/nfc_result.h"
11#include "core/hle/service/nfc/nfc_user.h" 11#include "core/hle/service/nfc/nfc_user.h"
@@ -54,7 +54,7 @@ IUser ::~IUser() {
54 availability_change_event->Close(); 54 availability_change_event->Close();
55} 55}
56 56
57void IUser::Initialize(Kernel::HLERequestContext& ctx) { 57void IUser::Initialize(HLERequestContext& ctx) {
58 LOG_INFO(Service_NFC, "called"); 58 LOG_INFO(Service_NFC, "called");
59 59
60 state = State::Initialized; 60 state = State::Initialized;
@@ -67,7 +67,7 @@ void IUser::Initialize(Kernel::HLERequestContext& ctx) {
67 rb.Push(ResultSuccess); 67 rb.Push(ResultSuccess);
68} 68}
69 69
70void IUser::Finalize(Kernel::HLERequestContext& ctx) { 70void IUser::Finalize(HLERequestContext& ctx) {
71 LOG_INFO(Service_NFC, "called"); 71 LOG_INFO(Service_NFC, "called");
72 72
73 state = State::NonInitialized; 73 state = State::NonInitialized;
@@ -80,7 +80,7 @@ void IUser::Finalize(Kernel::HLERequestContext& ctx) {
80 rb.Push(ResultSuccess); 80 rb.Push(ResultSuccess);
81} 81}
82 82
83void IUser::GetState(Kernel::HLERequestContext& ctx) { 83void IUser::GetState(HLERequestContext& ctx) {
84 LOG_DEBUG(Service_NFC, "called"); 84 LOG_DEBUG(Service_NFC, "called");
85 85
86 IPC::ResponseBuilder rb{ctx, 3}; 86 IPC::ResponseBuilder rb{ctx, 3};
@@ -88,7 +88,7 @@ void IUser::GetState(Kernel::HLERequestContext& ctx) {
88 rb.PushEnum(state); 88 rb.PushEnum(state);
89} 89}
90 90
91void IUser::IsNfcEnabled(Kernel::HLERequestContext& ctx) { 91void IUser::IsNfcEnabled(HLERequestContext& ctx) {
92 LOG_DEBUG(Service_NFC, "called"); 92 LOG_DEBUG(Service_NFC, "called");
93 93
94 IPC::ResponseBuilder rb{ctx, 3}; 94 IPC::ResponseBuilder rb{ctx, 3};
@@ -96,7 +96,7 @@ void IUser::IsNfcEnabled(Kernel::HLERequestContext& ctx) {
96 rb.Push(state != State::NonInitialized); 96 rb.Push(state != State::NonInitialized);
97} 97}
98 98
99void IUser::ListDevices(Kernel::HLERequestContext& ctx) { 99void IUser::ListDevices(HLERequestContext& ctx) {
100 LOG_DEBUG(Service_NFC, "called"); 100 LOG_DEBUG(Service_NFC, "called");
101 101
102 if (state == State::NonInitialized) { 102 if (state == State::NonInitialized) {
@@ -142,7 +142,7 @@ void IUser::ListDevices(Kernel::HLERequestContext& ctx) {
142 rb.Push(static_cast<s32>(nfp_devices.size())); 142 rb.Push(static_cast<s32>(nfp_devices.size()));
143} 143}
144 144
145void IUser::GetDeviceState(Kernel::HLERequestContext& ctx) { 145void IUser::GetDeviceState(HLERequestContext& ctx) {
146 IPC::RequestParser rp{ctx}; 146 IPC::RequestParser rp{ctx};
147 const auto device_handle{rp.Pop<u64>()}; 147 const auto device_handle{rp.Pop<u64>()};
148 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 148 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
@@ -160,7 +160,7 @@ void IUser::GetDeviceState(Kernel::HLERequestContext& ctx) {
160 rb.PushEnum(device.value()->GetCurrentState()); 160 rb.PushEnum(device.value()->GetCurrentState());
161} 161}
162 162
163void IUser::GetNpadId(Kernel::HLERequestContext& ctx) { 163void IUser::GetNpadId(HLERequestContext& ctx) {
164 IPC::RequestParser rp{ctx}; 164 IPC::RequestParser rp{ctx};
165 const auto device_handle{rp.Pop<u64>()}; 165 const auto device_handle{rp.Pop<u64>()};
166 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 166 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
@@ -184,7 +184,7 @@ void IUser::GetNpadId(Kernel::HLERequestContext& ctx) {
184 rb.PushEnum(device.value()->GetNpadId()); 184 rb.PushEnum(device.value()->GetNpadId());
185} 185}
186 186
187void IUser::AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx) { 187void IUser::AttachAvailabilityChangeEvent(HLERequestContext& ctx) {
188 LOG_INFO(Service_NFC, "called"); 188 LOG_INFO(Service_NFC, "called");
189 189
190 if (state == State::NonInitialized) { 190 if (state == State::NonInitialized) {
@@ -198,7 +198,7 @@ void IUser::AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx) {
198 rb.PushCopyObjects(availability_change_event->GetReadableEvent()); 198 rb.PushCopyObjects(availability_change_event->GetReadableEvent());
199} 199}
200 200
201void IUser::StartDetection(Kernel::HLERequestContext& ctx) { 201void IUser::StartDetection(HLERequestContext& ctx) {
202 IPC::RequestParser rp{ctx}; 202 IPC::RequestParser rp{ctx};
203 const auto device_handle{rp.Pop<u64>()}; 203 const auto device_handle{rp.Pop<u64>()};
204 const auto nfp_protocol{rp.PopEnum<NFP::TagProtocol>()}; 204 const auto nfp_protocol{rp.PopEnum<NFP::TagProtocol>()};
@@ -223,7 +223,7 @@ void IUser::StartDetection(Kernel::HLERequestContext& ctx) {
223 rb.Push(result); 223 rb.Push(result);
224} 224}
225 225
226void IUser::StopDetection(Kernel::HLERequestContext& ctx) { 226void IUser::StopDetection(HLERequestContext& ctx) {
227 IPC::RequestParser rp{ctx}; 227 IPC::RequestParser rp{ctx};
228 const auto device_handle{rp.Pop<u64>()}; 228 const auto device_handle{rp.Pop<u64>()};
229 LOG_INFO(Service_NFC, "called, device_handle={}", device_handle); 229 LOG_INFO(Service_NFC, "called, device_handle={}", device_handle);
@@ -247,7 +247,7 @@ void IUser::StopDetection(Kernel::HLERequestContext& ctx) {
247 rb.Push(result); 247 rb.Push(result);
248} 248}
249 249
250void IUser::GetTagInfo(Kernel::HLERequestContext& ctx) { 250void IUser::GetTagInfo(HLERequestContext& ctx) {
251 IPC::RequestParser rp{ctx}; 251 IPC::RequestParser rp{ctx};
252 const auto device_handle{rp.Pop<u64>()}; 252 const auto device_handle{rp.Pop<u64>()};
253 LOG_INFO(Service_NFC, "called, device_handle={}", device_handle); 253 LOG_INFO(Service_NFC, "called, device_handle={}", device_handle);
@@ -273,7 +273,7 @@ void IUser::GetTagInfo(Kernel::HLERequestContext& ctx) {
273 rb.Push(result); 273 rb.Push(result);
274} 274}
275 275
276void IUser::AttachActivateEvent(Kernel::HLERequestContext& ctx) { 276void IUser::AttachActivateEvent(HLERequestContext& ctx) {
277 IPC::RequestParser rp{ctx}; 277 IPC::RequestParser rp{ctx};
278 const auto device_handle{rp.Pop<u64>()}; 278 const auto device_handle{rp.Pop<u64>()};
279 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 279 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
@@ -297,7 +297,7 @@ void IUser::AttachActivateEvent(Kernel::HLERequestContext& ctx) {
297 rb.PushCopyObjects(device.value()->GetActivateEvent()); 297 rb.PushCopyObjects(device.value()->GetActivateEvent());
298} 298}
299 299
300void IUser::AttachDeactivateEvent(Kernel::HLERequestContext& ctx) { 300void IUser::AttachDeactivateEvent(HLERequestContext& ctx) {
301 IPC::RequestParser rp{ctx}; 301 IPC::RequestParser rp{ctx};
302 const auto device_handle{rp.Pop<u64>()}; 302 const auto device_handle{rp.Pop<u64>()};
303 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle); 303 LOG_DEBUG(Service_NFC, "called, device_handle={}", device_handle);
@@ -321,7 +321,7 @@ void IUser::AttachDeactivateEvent(Kernel::HLERequestContext& ctx) {
321 rb.PushCopyObjects(device.value()->GetDeactivateEvent()); 321 rb.PushCopyObjects(device.value()->GetDeactivateEvent());
322} 322}
323 323
324void IUser::SendCommandByPassThrough(Kernel::HLERequestContext& ctx) { 324void IUser::SendCommandByPassThrough(HLERequestContext& ctx) {
325 IPC::RequestParser rp{ctx}; 325 IPC::RequestParser rp{ctx};
326 const auto device_handle{rp.Pop<u64>()}; 326 const auto device_handle{rp.Pop<u64>()};
327 const auto timeout{rp.PopRaw<Time::Clock::TimeSpanType>()}; 327 const auto timeout{rp.PopRaw<Time::Clock::TimeSpanType>()};
diff --git a/src/core/hle/service/nfc/nfc_user.h b/src/core/hle/service/nfc/nfc_user.h
index a5a4f12f9..aee046ae8 100644
--- a/src/core/hle/service/nfc/nfc_user.h
+++ b/src/core/hle/service/nfc/nfc_user.h
@@ -24,20 +24,20 @@ private:
24 Initialized, 24 Initialized,
25 }; 25 };
26 26
27 void Initialize(Kernel::HLERequestContext& ctx); 27 void Initialize(HLERequestContext& ctx);
28 void Finalize(Kernel::HLERequestContext& ctx); 28 void Finalize(HLERequestContext& ctx);
29 void GetState(Kernel::HLERequestContext& ctx); 29 void GetState(HLERequestContext& ctx);
30 void IsNfcEnabled(Kernel::HLERequestContext& ctx); 30 void IsNfcEnabled(HLERequestContext& ctx);
31 void ListDevices(Kernel::HLERequestContext& ctx); 31 void ListDevices(HLERequestContext& ctx);
32 void GetDeviceState(Kernel::HLERequestContext& ctx); 32 void GetDeviceState(HLERequestContext& ctx);
33 void GetNpadId(Kernel::HLERequestContext& ctx); 33 void GetNpadId(HLERequestContext& ctx);
34 void AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx); 34 void AttachAvailabilityChangeEvent(HLERequestContext& ctx);
35 void StartDetection(Kernel::HLERequestContext& ctx); 35 void StartDetection(HLERequestContext& ctx);
36 void StopDetection(Kernel::HLERequestContext& ctx); 36 void StopDetection(HLERequestContext& ctx);
37 void GetTagInfo(Kernel::HLERequestContext& ctx); 37 void GetTagInfo(HLERequestContext& ctx);
38 void AttachActivateEvent(Kernel::HLERequestContext& ctx); 38 void AttachActivateEvent(HLERequestContext& ctx);
39 void AttachDeactivateEvent(Kernel::HLERequestContext& ctx); 39 void AttachDeactivateEvent(HLERequestContext& ctx);
40 void SendCommandByPassThrough(Kernel::HLERequestContext& ctx); 40 void SendCommandByPassThrough(HLERequestContext& ctx);
41 41
42 std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle); 42 std::optional<std::shared_ptr<NfcDevice>> GetNfcDevice(u64 handle);
43 43
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index 0cb55ca49..e262dc2f2 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -2,9 +2,10 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h" 5#include "core/hle/service/ipc_helpers.h"
6#include "core/hle/service/nfp/nfp.h" 6#include "core/hle/service/nfp/nfp.h"
7#include "core/hle/service/nfp/nfp_user.h" 7#include "core/hle/service/nfp/nfp_user.h"
8#include "core/hle/service/server_manager.h"
8 9
9namespace Service::NFP { 10namespace Service::NFP {
10 11
@@ -21,7 +22,7 @@ public:
21 } 22 }
22 23
23private: 24private:
24 void CreateUserInterface(Kernel::HLERequestContext& ctx) { 25 void CreateUserInterface(HLERequestContext& ctx) {
25 LOG_DEBUG(Service_NFP, "called"); 26 LOG_DEBUG(Service_NFP, "called");
26 27
27 if (user_interface == nullptr) { 28 if (user_interface == nullptr) {
@@ -36,8 +37,11 @@ private:
36 std::shared_ptr<IUser> user_interface; 37 std::shared_ptr<IUser> user_interface;
37}; 38};
38 39
39void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 40void LoopProcess(Core::System& system) {
40 std::make_shared<IUserManager>(system)->InstallAsService(service_manager); 41 auto server_manager = std::make_unique<ServerManager>(system);
42
43 server_manager->RegisterNamedService("nfp:user", std::make_shared<IUserManager>(system));
44 ServerManager::RunServer(std::move(server_manager));
41} 45}
42 46
43} // namespace Service::NFP 47} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h
index a25c362b8..a5aac710b 100644
--- a/src/core/hle/service/nfp/nfp.h
+++ b/src/core/hle/service/nfp/nfp.h
@@ -7,6 +7,6 @@
7 7
8namespace Service::NFP { 8namespace Service::NFP {
9 9
10void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); 10void LoopProcess(Core::System& system);
11 11
12} // namespace Service::NFP 12} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp
index 7a6bbbba7..1bdc42741 100644
--- a/src/core/hle/service/nfp/nfp_device.cpp
+++ b/src/core/hle/service/nfp/nfp_device.cpp
@@ -11,8 +11,8 @@
11#include "core/hid/emulated_controller.h" 11#include "core/hid/emulated_controller.h"
12#include "core/hid/hid_core.h" 12#include "core/hid/hid_core.h"
13#include "core/hid/hid_types.h" 13#include "core/hid/hid_types.h"
14#include "core/hle/ipc_helpers.h"
15#include "core/hle/kernel/k_event.h" 14#include "core/hle/kernel/k_event.h"
15#include "core/hle/service/ipc_helpers.h"
16#include "core/hle/service/mii/mii_manager.h" 16#include "core/hle/service/mii/mii_manager.h"
17#include "core/hle/service/mii/types.h" 17#include "core/hle/service/mii/types.h"
18#include "core/hle/service/nfp/amiibo_crypto.h" 18#include "core/hle/service/nfp/amiibo_crypto.h"
diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp
index a4d3d1bc7..4e8534113 100644
--- a/src/core/hle/service/nfp/nfp_user.cpp
+++ b/src/core/hle/service/nfp/nfp_user.cpp
@@ -4,8 +4,8 @@
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hid/hid_types.h" 6#include "core/hid/hid_types.h"
7#include "core/hle/ipc_helpers.h"
8#include "core/hle/kernel/k_event.h" 7#include "core/hle/kernel/k_event.h"
8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/nfp/nfp_device.h" 9#include "core/hle/service/nfp/nfp_device.h"
10#include "core/hle/service/nfp/nfp_result.h" 10#include "core/hle/service/nfp/nfp_result.h"
11#include "core/hle/service/nfp/nfp_user.h" 11#include "core/hle/service/nfp/nfp_user.h"
@@ -56,7 +56,7 @@ IUser ::~IUser() {
56 availability_change_event->Close(); 56 availability_change_event->Close();
57} 57}
58 58
59void IUser::Initialize(Kernel::HLERequestContext& ctx) { 59void IUser::Initialize(HLERequestContext& ctx) {
60 LOG_INFO(Service_NFP, "called"); 60 LOG_INFO(Service_NFP, "called");
61 61
62 state = State::Initialized; 62 state = State::Initialized;
@@ -69,7 +69,7 @@ void IUser::Initialize(Kernel::HLERequestContext& ctx) {
69 rb.Push(ResultSuccess); 69 rb.Push(ResultSuccess);
70} 70}
71 71
72void IUser::Finalize(Kernel::HLERequestContext& ctx) { 72void IUser::Finalize(HLERequestContext& ctx) {
73 LOG_INFO(Service_NFP, "called"); 73 LOG_INFO(Service_NFP, "called");
74 74
75 state = State::NonInitialized; 75 state = State::NonInitialized;
@@ -82,7 +82,7 @@ void IUser::Finalize(Kernel::HLERequestContext& ctx) {
82 rb.Push(ResultSuccess); 82 rb.Push(ResultSuccess);
83} 83}
84 84
85void IUser::ListDevices(Kernel::HLERequestContext& ctx) { 85void IUser::ListDevices(HLERequestContext& ctx) {
86 LOG_DEBUG(Service_NFP, "called"); 86 LOG_DEBUG(Service_NFP, "called");
87 87
88 if (state == State::NonInitialized) { 88 if (state == State::NonInitialized) {
@@ -128,7 +128,7 @@ void IUser::ListDevices(Kernel::HLERequestContext& ctx) {
128 rb.Push(static_cast<s32>(nfp_devices.size())); 128 rb.Push(static_cast<s32>(nfp_devices.size()));
129} 129}
130 130
131void IUser::StartDetection(Kernel::HLERequestContext& ctx) { 131void IUser::StartDetection(HLERequestContext& ctx) {
132 IPC::RequestParser rp{ctx}; 132 IPC::RequestParser rp{ctx};
133 const auto device_handle{rp.Pop<u64>()}; 133 const auto device_handle{rp.Pop<u64>()};
134 const auto nfp_protocol{rp.PopEnum<TagProtocol>()}; 134 const auto nfp_protocol{rp.PopEnum<TagProtocol>()};
@@ -153,7 +153,7 @@ void IUser::StartDetection(Kernel::HLERequestContext& ctx) {
153 rb.Push(result); 153 rb.Push(result);
154} 154}
155 155
156void IUser::StopDetection(Kernel::HLERequestContext& ctx) { 156void IUser::StopDetection(HLERequestContext& ctx) {
157 IPC::RequestParser rp{ctx}; 157 IPC::RequestParser rp{ctx};
158 const auto device_handle{rp.Pop<u64>()}; 158 const auto device_handle{rp.Pop<u64>()};
159 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); 159 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
@@ -177,7 +177,7 @@ void IUser::StopDetection(Kernel::HLERequestContext& ctx) {
177 rb.Push(result); 177 rb.Push(result);
178} 178}
179 179
180void IUser::Mount(Kernel::HLERequestContext& ctx) { 180void IUser::Mount(HLERequestContext& ctx) {
181 IPC::RequestParser rp{ctx}; 181 IPC::RequestParser rp{ctx};
182 const auto device_handle{rp.Pop<u64>()}; 182 const auto device_handle{rp.Pop<u64>()};
183 const auto model_type{rp.PopEnum<ModelType>()}; 183 const auto model_type{rp.PopEnum<ModelType>()};
@@ -204,7 +204,7 @@ void IUser::Mount(Kernel::HLERequestContext& ctx) {
204 rb.Push(result); 204 rb.Push(result);
205} 205}
206 206
207void IUser::Unmount(Kernel::HLERequestContext& ctx) { 207void IUser::Unmount(HLERequestContext& ctx) {
208 IPC::RequestParser rp{ctx}; 208 IPC::RequestParser rp{ctx};
209 const auto device_handle{rp.Pop<u64>()}; 209 const auto device_handle{rp.Pop<u64>()};
210 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); 210 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
@@ -228,7 +228,7 @@ void IUser::Unmount(Kernel::HLERequestContext& ctx) {
228 rb.Push(result); 228 rb.Push(result);
229} 229}
230 230
231void IUser::OpenApplicationArea(Kernel::HLERequestContext& ctx) { 231void IUser::OpenApplicationArea(HLERequestContext& ctx) {
232 IPC::RequestParser rp{ctx}; 232 IPC::RequestParser rp{ctx};
233 const auto device_handle{rp.Pop<u64>()}; 233 const auto device_handle{rp.Pop<u64>()};
234 const auto access_id{rp.Pop<u32>()}; 234 const auto access_id{rp.Pop<u32>()};
@@ -253,7 +253,7 @@ void IUser::OpenApplicationArea(Kernel::HLERequestContext& ctx) {
253 rb.Push(result); 253 rb.Push(result);
254} 254}
255 255
256void IUser::GetApplicationArea(Kernel::HLERequestContext& ctx) { 256void IUser::GetApplicationArea(HLERequestContext& ctx) {
257 IPC::RequestParser rp{ctx}; 257 IPC::RequestParser rp{ctx};
258 const auto device_handle{rp.Pop<u64>()}; 258 const auto device_handle{rp.Pop<u64>()};
259 const auto data_size = ctx.GetWriteBufferSize(); 259 const auto data_size = ctx.GetWriteBufferSize();
@@ -287,7 +287,7 @@ void IUser::GetApplicationArea(Kernel::HLERequestContext& ctx) {
287 rb.Push(static_cast<u32>(data_size)); 287 rb.Push(static_cast<u32>(data_size));
288} 288}
289 289
290void IUser::SetApplicationArea(Kernel::HLERequestContext& ctx) { 290void IUser::SetApplicationArea(HLERequestContext& ctx) {
291 IPC::RequestParser rp{ctx}; 291 IPC::RequestParser rp{ctx};
292 const auto device_handle{rp.Pop<u64>()}; 292 const auto device_handle{rp.Pop<u64>()};
293 const auto data{ctx.ReadBuffer()}; 293 const auto data{ctx.ReadBuffer()};
@@ -318,7 +318,7 @@ void IUser::SetApplicationArea(Kernel::HLERequestContext& ctx) {
318 rb.Push(result); 318 rb.Push(result);
319} 319}
320 320
321void IUser::Flush(Kernel::HLERequestContext& ctx) { 321void IUser::Flush(HLERequestContext& ctx) {
322 IPC::RequestParser rp{ctx}; 322 IPC::RequestParser rp{ctx};
323 const auto device_handle{rp.Pop<u64>()}; 323 const auto device_handle{rp.Pop<u64>()};
324 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); 324 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
@@ -342,7 +342,7 @@ void IUser::Flush(Kernel::HLERequestContext& ctx) {
342 rb.Push(result); 342 rb.Push(result);
343} 343}
344 344
345void IUser::Restore(Kernel::HLERequestContext& ctx) { 345void IUser::Restore(HLERequestContext& ctx) {
346 IPC::RequestParser rp{ctx}; 346 IPC::RequestParser rp{ctx};
347 const auto device_handle{rp.Pop<u64>()}; 347 const auto device_handle{rp.Pop<u64>()};
348 LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}", device_handle); 348 LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}", device_handle);
@@ -366,7 +366,7 @@ void IUser::Restore(Kernel::HLERequestContext& ctx) {
366 rb.Push(result); 366 rb.Push(result);
367} 367}
368 368
369void IUser::CreateApplicationArea(Kernel::HLERequestContext& ctx) { 369void IUser::CreateApplicationArea(HLERequestContext& ctx) {
370 IPC::RequestParser rp{ctx}; 370 IPC::RequestParser rp{ctx};
371 const auto device_handle{rp.Pop<u64>()}; 371 const auto device_handle{rp.Pop<u64>()};
372 const auto access_id{rp.Pop<u32>()}; 372 const auto access_id{rp.Pop<u32>()};
@@ -399,7 +399,7 @@ void IUser::CreateApplicationArea(Kernel::HLERequestContext& ctx) {
399 rb.Push(result); 399 rb.Push(result);
400} 400}
401 401
402void IUser::GetTagInfo(Kernel::HLERequestContext& ctx) { 402void IUser::GetTagInfo(HLERequestContext& ctx) {
403 IPC::RequestParser rp{ctx}; 403 IPC::RequestParser rp{ctx};
404 const auto device_handle{rp.Pop<u64>()}; 404 const auto device_handle{rp.Pop<u64>()};
405 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); 405 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
@@ -425,7 +425,7 @@ void IUser::GetTagInfo(Kernel::HLERequestContext& ctx) {
425 rb.Push(result); 425 rb.Push(result);
426} 426}
427 427
428void IUser::GetRegisterInfo(Kernel::HLERequestContext& ctx) { 428void IUser::GetRegisterInfo(HLERequestContext& ctx) {
429 IPC::RequestParser rp{ctx}; 429 IPC::RequestParser rp{ctx};
430 const auto device_handle{rp.Pop<u64>()}; 430 const auto device_handle{rp.Pop<u64>()};
431 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); 431 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
@@ -451,7 +451,7 @@ void IUser::GetRegisterInfo(Kernel::HLERequestContext& ctx) {
451 rb.Push(result); 451 rb.Push(result);
452} 452}
453 453
454void IUser::GetCommonInfo(Kernel::HLERequestContext& ctx) { 454void IUser::GetCommonInfo(HLERequestContext& ctx) {
455 IPC::RequestParser rp{ctx}; 455 IPC::RequestParser rp{ctx};
456 const auto device_handle{rp.Pop<u64>()}; 456 const auto device_handle{rp.Pop<u64>()};
457 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); 457 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
@@ -477,7 +477,7 @@ void IUser::GetCommonInfo(Kernel::HLERequestContext& ctx) {
477 rb.Push(result); 477 rb.Push(result);
478} 478}
479 479
480void IUser::GetModelInfo(Kernel::HLERequestContext& ctx) { 480void IUser::GetModelInfo(HLERequestContext& ctx) {
481 IPC::RequestParser rp{ctx}; 481 IPC::RequestParser rp{ctx};
482 const auto device_handle{rp.Pop<u64>()}; 482 const auto device_handle{rp.Pop<u64>()};
483 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); 483 LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
@@ -503,7 +503,7 @@ void IUser::GetModelInfo(Kernel::HLERequestContext& ctx) {
503 rb.Push(result); 503 rb.Push(result);
504} 504}
505 505
506void IUser::AttachActivateEvent(Kernel::HLERequestContext& ctx) { 506void IUser::AttachActivateEvent(HLERequestContext& ctx) {
507 IPC::RequestParser rp{ctx}; 507 IPC::RequestParser rp{ctx};
508 const auto device_handle{rp.Pop<u64>()}; 508 const auto device_handle{rp.Pop<u64>()};
509 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle); 509 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
@@ -527,7 +527,7 @@ void IUser::AttachActivateEvent(Kernel::HLERequestContext& ctx) {
527 rb.PushCopyObjects(device.value()->GetActivateEvent()); 527 rb.PushCopyObjects(device.value()->GetActivateEvent());
528} 528}
529 529
530void IUser::AttachDeactivateEvent(Kernel::HLERequestContext& ctx) { 530void IUser::AttachDeactivateEvent(HLERequestContext& ctx) {
531 IPC::RequestParser rp{ctx}; 531 IPC::RequestParser rp{ctx};
532 const auto device_handle{rp.Pop<u64>()}; 532 const auto device_handle{rp.Pop<u64>()};
533 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle); 533 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
@@ -551,7 +551,7 @@ void IUser::AttachDeactivateEvent(Kernel::HLERequestContext& ctx) {
551 rb.PushCopyObjects(device.value()->GetDeactivateEvent()); 551 rb.PushCopyObjects(device.value()->GetDeactivateEvent());
552} 552}
553 553
554void IUser::GetState(Kernel::HLERequestContext& ctx) { 554void IUser::GetState(HLERequestContext& ctx) {
555 LOG_DEBUG(Service_NFP, "called"); 555 LOG_DEBUG(Service_NFP, "called");
556 556
557 IPC::ResponseBuilder rb{ctx, 3}; 557 IPC::ResponseBuilder rb{ctx, 3};
@@ -559,7 +559,7 @@ void IUser::GetState(Kernel::HLERequestContext& ctx) {
559 rb.PushEnum(state); 559 rb.PushEnum(state);
560} 560}
561 561
562void IUser::GetDeviceState(Kernel::HLERequestContext& ctx) { 562void IUser::GetDeviceState(HLERequestContext& ctx) {
563 IPC::RequestParser rp{ctx}; 563 IPC::RequestParser rp{ctx};
564 const auto device_handle{rp.Pop<u64>()}; 564 const auto device_handle{rp.Pop<u64>()};
565 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle); 565 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
@@ -577,7 +577,7 @@ void IUser::GetDeviceState(Kernel::HLERequestContext& ctx) {
577 rb.PushEnum(device.value()->GetCurrentState()); 577 rb.PushEnum(device.value()->GetCurrentState());
578} 578}
579 579
580void IUser::GetNpadId(Kernel::HLERequestContext& ctx) { 580void IUser::GetNpadId(HLERequestContext& ctx) {
581 IPC::RequestParser rp{ctx}; 581 IPC::RequestParser rp{ctx};
582 const auto device_handle{rp.Pop<u64>()}; 582 const auto device_handle{rp.Pop<u64>()};
583 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle); 583 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
@@ -601,7 +601,7 @@ void IUser::GetNpadId(Kernel::HLERequestContext& ctx) {
601 rb.PushEnum(device.value()->GetNpadId()); 601 rb.PushEnum(device.value()->GetNpadId());
602} 602}
603 603
604void IUser::GetApplicationAreaSize(Kernel::HLERequestContext& ctx) { 604void IUser::GetApplicationAreaSize(HLERequestContext& ctx) {
605 IPC::RequestParser rp{ctx}; 605 IPC::RequestParser rp{ctx};
606 const auto device_handle{rp.Pop<u64>()}; 606 const auto device_handle{rp.Pop<u64>()};
607 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle); 607 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
@@ -619,7 +619,7 @@ void IUser::GetApplicationAreaSize(Kernel::HLERequestContext& ctx) {
619 rb.Push(device.value()->GetApplicationAreaSize()); 619 rb.Push(device.value()->GetApplicationAreaSize());
620} 620}
621 621
622void IUser::AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx) { 622void IUser::AttachAvailabilityChangeEvent(HLERequestContext& ctx) {
623 LOG_INFO(Service_NFP, "called"); 623 LOG_INFO(Service_NFP, "called");
624 624
625 if (state == State::NonInitialized) { 625 if (state == State::NonInitialized) {
@@ -633,7 +633,7 @@ void IUser::AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx) {
633 rb.PushCopyObjects(availability_change_event->GetReadableEvent()); 633 rb.PushCopyObjects(availability_change_event->GetReadableEvent());
634} 634}
635 635
636void IUser::RecreateApplicationArea(Kernel::HLERequestContext& ctx) { 636void IUser::RecreateApplicationArea(HLERequestContext& ctx) {
637 IPC::RequestParser rp{ctx}; 637 IPC::RequestParser rp{ctx};
638 const auto device_handle{rp.Pop<u64>()}; 638 const auto device_handle{rp.Pop<u64>()};
639 const auto access_id{rp.Pop<u32>()}; 639 const auto access_id{rp.Pop<u32>()};
diff --git a/src/core/hle/service/nfp/nfp_user.h b/src/core/hle/service/nfp/nfp_user.h
index 7e9a90af8..1f3ff2ea8 100644
--- a/src/core/hle/service/nfp/nfp_user.h
+++ b/src/core/hle/service/nfp/nfp_user.h
@@ -24,31 +24,31 @@ private:
24 Initialized, 24 Initialized,
25 }; 25 };
26 26
27 void Initialize(Kernel::HLERequestContext& ctx); 27 void Initialize(HLERequestContext& ctx);
28 void Finalize(Kernel::HLERequestContext& ctx); 28 void Finalize(HLERequestContext& ctx);
29 void ListDevices(Kernel::HLERequestContext& ctx); 29 void ListDevices(HLERequestContext& ctx);
30 void StartDetection(Kernel::HLERequestContext& ctx); 30 void StartDetection(HLERequestContext& ctx);
31 void StopDetection(Kernel::HLERequestContext& ctx); 31 void StopDetection(HLERequestContext& ctx);
32 void Mount(Kernel::HLERequestContext& ctx); 32 void Mount(HLERequestContext& ctx);
33 void Unmount(Kernel::HLERequestContext& ctx); 33 void Unmount(HLERequestContext& ctx);
34 void OpenApplicationArea(Kernel::HLERequestContext& ctx); 34 void OpenApplicationArea(HLERequestContext& ctx);
35 void GetApplicationArea(Kernel::HLERequestContext& ctx); 35 void GetApplicationArea(HLERequestContext& ctx);
36 void SetApplicationArea(Kernel::HLERequestContext& ctx); 36 void SetApplicationArea(HLERequestContext& ctx);
37 void Flush(Kernel::HLERequestContext& ctx); 37 void Flush(HLERequestContext& ctx);
38 void Restore(Kernel::HLERequestContext& ctx); 38 void Restore(HLERequestContext& ctx);
39 void CreateApplicationArea(Kernel::HLERequestContext& ctx); 39 void CreateApplicationArea(HLERequestContext& ctx);
40 void GetTagInfo(Kernel::HLERequestContext& ctx); 40 void GetTagInfo(HLERequestContext& ctx);
41 void GetRegisterInfo(Kernel::HLERequestContext& ctx); 41 void GetRegisterInfo(HLERequestContext& ctx);
42 void GetCommonInfo(Kernel::HLERequestContext& ctx); 42 void GetCommonInfo(HLERequestContext& ctx);
43 void GetModelInfo(Kernel::HLERequestContext& ctx); 43 void GetModelInfo(HLERequestContext& ctx);
44 void AttachActivateEvent(Kernel::HLERequestContext& ctx); 44 void AttachActivateEvent(HLERequestContext& ctx);
45 void AttachDeactivateEvent(Kernel::HLERequestContext& ctx); 45 void AttachDeactivateEvent(HLERequestContext& ctx);
46 void GetState(Kernel::HLERequestContext& ctx); 46 void GetState(HLERequestContext& ctx);
47 void GetDeviceState(Kernel::HLERequestContext& ctx); 47 void GetDeviceState(HLERequestContext& ctx);
48 void GetNpadId(Kernel::HLERequestContext& ctx); 48 void GetNpadId(HLERequestContext& ctx);
49 void GetApplicationAreaSize(Kernel::HLERequestContext& ctx); 49 void GetApplicationAreaSize(HLERequestContext& ctx);
50 void AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx); 50 void AttachAvailabilityChangeEvent(HLERequestContext& ctx);
51 void RecreateApplicationArea(Kernel::HLERequestContext& ctx); 51 void RecreateApplicationArea(HLERequestContext& ctx);
52 52
53 std::optional<std::shared_ptr<NfpDevice>> GetNfpDevice(u64 handle); 53 std::optional<std::shared_ptr<NfpDevice>> GetNfpDevice(u64 handle);
54 54
diff --git a/src/core/hle/service/ngct/ngct.cpp b/src/core/hle/service/ngct/ngct.cpp
index 8af8a835d..493c80ed2 100644
--- a/src/core/hle/service/ngct/ngct.cpp
+++ b/src/core/hle/service/ngct/ngct.cpp
@@ -3,8 +3,9 @@
3 3
4#include "common/string_util.h" 4#include "common/string_util.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/ipc_helpers.h" 6#include "core/hle/service/ipc_helpers.h"
7#include "core/hle/service/ngct/ngct.h" 7#include "core/hle/service/ngct/ngct.h"
8#include "core/hle/service/server_manager.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9 10
10namespace Service::NGCT { 11namespace Service::NGCT {
@@ -23,7 +24,7 @@ public:
23 } 24 }
24 25
25private: 26private:
26 void Match(Kernel::HLERequestContext& ctx) { 27 void Match(HLERequestContext& ctx) {
27 const auto buffer = ctx.ReadBuffer(); 28 const auto buffer = ctx.ReadBuffer();
28 const auto text = Common::StringFromFixedZeroTerminatedBuffer( 29 const auto text = Common::StringFromFixedZeroTerminatedBuffer(
29 reinterpret_cast<const char*>(buffer.data()), buffer.size()); 30 reinterpret_cast<const char*>(buffer.data()), buffer.size());
@@ -36,7 +37,7 @@ private:
36 rb.Push(false); 37 rb.Push(false);
37 } 38 }
38 39
39 void Filter(Kernel::HLERequestContext& ctx) { 40 void Filter(HLERequestContext& ctx) {
40 const auto buffer = ctx.ReadBuffer(); 41 const auto buffer = ctx.ReadBuffer();
41 const auto text = Common::StringFromFixedZeroTerminatedBuffer( 42 const auto text = Common::StringFromFixedZeroTerminatedBuffer(
42 reinterpret_cast<const char*>(buffer.data()), buffer.size()); 43 reinterpret_cast<const char*>(buffer.data()), buffer.size());
@@ -51,8 +52,11 @@ private:
51 } 52 }
52}; 53};
53 54
54void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 55void LoopProcess(Core::System& system) {
55 std::make_shared<IService>(system)->InstallAsService(system.ServiceManager()); 56 auto server_manager = std::make_unique<ServerManager>(system);
57
58 server_manager->RegisterNamedService("ngct:u", std::make_shared<IService>(system));
59 ServerManager::RunServer(std::move(server_manager));
56} 60}
57 61
58} // namespace Service::NGCT 62} // namespace Service::NGCT
diff --git a/src/core/hle/service/ngct/ngct.h b/src/core/hle/service/ngct/ngct.h
index 370bd4a25..27c34dad4 100644
--- a/src/core/hle/service/ngct/ngct.h
+++ b/src/core/hle/service/ngct/ngct.h
@@ -7,13 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::NGCT { 10namespace Service::NGCT {
15 11
16/// Registers all NGCT services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::NGCT 14} // namespace Service::NGCT
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index 5d32adf64..0c042f412 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -2,10 +2,11 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/kernel/k_event.h" 5#include "core/hle/kernel/k_event.h"
6#include "core/hle/service/ipc_helpers.h"
7#include "core/hle/service/kernel_helpers.h" 7#include "core/hle/service/kernel_helpers.h"
8#include "core/hle/service/nifm/nifm.h" 8#include "core/hle/service/nifm/nifm.h"
9#include "core/hle/service/server_manager.h"
9 10
10namespace { 11namespace {
11 12
@@ -216,7 +217,7 @@ public:
216 } 217 }
217 218
218private: 219private:
219 void Submit(Kernel::HLERequestContext& ctx) { 220 void Submit(HLERequestContext& ctx) {
220 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 221 LOG_WARNING(Service_NIFM, "(STUBBED) called");
221 222
222 if (state == RequestState::NotSubmitted) { 223 if (state == RequestState::NotSubmitted) {
@@ -227,7 +228,7 @@ private:
227 rb.Push(ResultSuccess); 228 rb.Push(ResultSuccess);
228 } 229 }
229 230
230 void GetRequestState(Kernel::HLERequestContext& ctx) { 231 void GetRequestState(HLERequestContext& ctx) {
231 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 232 LOG_WARNING(Service_NIFM, "(STUBBED) called");
232 233
233 IPC::ResponseBuilder rb{ctx, 3}; 234 IPC::ResponseBuilder rb{ctx, 3};
@@ -235,7 +236,7 @@ private:
235 rb.PushEnum(state); 236 rb.PushEnum(state);
236 } 237 }
237 238
238 void GetResult(Kernel::HLERequestContext& ctx) { 239 void GetResult(HLERequestContext& ctx) {
239 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 240 LOG_WARNING(Service_NIFM, "(STUBBED) called");
240 241
241 const auto result = [this] { 242 const auto result = [this] {
@@ -260,7 +261,7 @@ private:
260 rb.Push(result); 261 rb.Push(result);
261 } 262 }
262 263
263 void GetSystemEventReadableHandles(Kernel::HLERequestContext& ctx) { 264 void GetSystemEventReadableHandles(HLERequestContext& ctx) {
264 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 265 LOG_WARNING(Service_NIFM, "(STUBBED) called");
265 266
266 IPC::ResponseBuilder rb{ctx, 2, 2}; 267 IPC::ResponseBuilder rb{ctx, 2, 2};
@@ -268,21 +269,21 @@ private:
268 rb.PushCopyObjects(event1->GetReadableEvent(), event2->GetReadableEvent()); 269 rb.PushCopyObjects(event1->GetReadableEvent(), event2->GetReadableEvent());
269 } 270 }
270 271
271 void Cancel(Kernel::HLERequestContext& ctx) { 272 void Cancel(HLERequestContext& ctx) {
272 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 273 LOG_WARNING(Service_NIFM, "(STUBBED) called");
273 274
274 IPC::ResponseBuilder rb{ctx, 2}; 275 IPC::ResponseBuilder rb{ctx, 2};
275 rb.Push(ResultSuccess); 276 rb.Push(ResultSuccess);
276 } 277 }
277 278
278 void SetConnectionConfirmationOption(Kernel::HLERequestContext& ctx) { 279 void SetConnectionConfirmationOption(HLERequestContext& ctx) {
279 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 280 LOG_WARNING(Service_NIFM, "(STUBBED) called");
280 281
281 IPC::ResponseBuilder rb{ctx, 2}; 282 IPC::ResponseBuilder rb{ctx, 2};
282 rb.Push(ResultSuccess); 283 rb.Push(ResultSuccess);
283 } 284 }
284 285
285 void GetAppletInfo(Kernel::HLERequestContext& ctx) { 286 void GetAppletInfo(HLERequestContext& ctx) {
286 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 287 LOG_WARNING(Service_NIFM, "(STUBBED) called");
287 288
288 std::vector<u8> out_buffer(ctx.GetWriteBufferSize()); 289 std::vector<u8> out_buffer(ctx.GetWriteBufferSize());
@@ -321,7 +322,7 @@ public:
321 } 322 }
322}; 323};
323 324
324void IGeneralService::GetClientId(Kernel::HLERequestContext& ctx) { 325void IGeneralService::GetClientId(HLERequestContext& ctx) {
325 static constexpr u32 client_id = 1; 326 static constexpr u32 client_id = 1;
326 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 327 LOG_WARNING(Service_NIFM, "(STUBBED) called");
327 328
@@ -330,7 +331,7 @@ void IGeneralService::GetClientId(Kernel::HLERequestContext& ctx) {
330 rb.Push<u64>(client_id); // Client ID needs to be non zero otherwise it's considered invalid 331 rb.Push<u64>(client_id); // Client ID needs to be non zero otherwise it's considered invalid
331} 332}
332 333
333void IGeneralService::CreateScanRequest(Kernel::HLERequestContext& ctx) { 334void IGeneralService::CreateScanRequest(HLERequestContext& ctx) {
334 LOG_DEBUG(Service_NIFM, "called"); 335 LOG_DEBUG(Service_NIFM, "called");
335 336
336 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 337 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -339,7 +340,7 @@ void IGeneralService::CreateScanRequest(Kernel::HLERequestContext& ctx) {
339 rb.PushIpcInterface<IScanRequest>(system); 340 rb.PushIpcInterface<IScanRequest>(system);
340} 341}
341 342
342void IGeneralService::CreateRequest(Kernel::HLERequestContext& ctx) { 343void IGeneralService::CreateRequest(HLERequestContext& ctx) {
343 LOG_DEBUG(Service_NIFM, "called"); 344 LOG_DEBUG(Service_NIFM, "called");
344 345
345 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 346 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -348,7 +349,7 @@ void IGeneralService::CreateRequest(Kernel::HLERequestContext& ctx) {
348 rb.PushIpcInterface<IRequest>(system); 349 rb.PushIpcInterface<IRequest>(system);
349} 350}
350 351
351void IGeneralService::GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx) { 352void IGeneralService::GetCurrentNetworkProfile(HLERequestContext& ctx) {
352 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 353 LOG_WARNING(Service_NIFM, "(STUBBED) called");
353 354
354 const auto net_iface = Network::GetSelectedNetworkInterface(); 355 const auto net_iface = Network::GetSelectedNetworkInterface();
@@ -407,14 +408,14 @@ void IGeneralService::GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx) {
407 rb.Push(ResultSuccess); 408 rb.Push(ResultSuccess);
408} 409}
409 410
410void IGeneralService::RemoveNetworkProfile(Kernel::HLERequestContext& ctx) { 411void IGeneralService::RemoveNetworkProfile(HLERequestContext& ctx) {
411 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 412 LOG_WARNING(Service_NIFM, "(STUBBED) called");
412 413
413 IPC::ResponseBuilder rb{ctx, 2}; 414 IPC::ResponseBuilder rb{ctx, 2};
414 rb.Push(ResultSuccess); 415 rb.Push(ResultSuccess);
415} 416}
416 417
417void IGeneralService::GetCurrentIpAddress(Kernel::HLERequestContext& ctx) { 418void IGeneralService::GetCurrentIpAddress(HLERequestContext& ctx) {
418 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 419 LOG_WARNING(Service_NIFM, "(STUBBED) called");
419 420
420 auto ipv4 = Network::GetHostIPv4Address(); 421 auto ipv4 = Network::GetHostIPv4Address();
@@ -435,7 +436,7 @@ void IGeneralService::GetCurrentIpAddress(Kernel::HLERequestContext& ctx) {
435 rb.PushRaw(*ipv4); 436 rb.PushRaw(*ipv4);
436} 437}
437 438
438void IGeneralService::CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) { 439void IGeneralService::CreateTemporaryNetworkProfile(HLERequestContext& ctx) {
439 LOG_DEBUG(Service_NIFM, "called"); 440 LOG_DEBUG(Service_NIFM, "called");
440 441
441 ASSERT_MSG(ctx.GetReadBufferSize() == 0x17c, "SfNetworkProfileData is not the correct size"); 442 ASSERT_MSG(ctx.GetReadBufferSize() == 0x17c, "SfNetworkProfileData is not the correct size");
@@ -450,7 +451,7 @@ void IGeneralService::CreateTemporaryNetworkProfile(Kernel::HLERequestContext& c
450 rb.PushRaw<u128>(uuid); 451 rb.PushRaw<u128>(uuid);
451} 452}
452 453
453void IGeneralService::GetCurrentIpConfigInfo(Kernel::HLERequestContext& ctx) { 454void IGeneralService::GetCurrentIpConfigInfo(HLERequestContext& ctx) {
454 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 455 LOG_WARNING(Service_NIFM, "(STUBBED) called");
455 456
456 struct IpConfigInfo { 457 struct IpConfigInfo {
@@ -494,7 +495,7 @@ void IGeneralService::GetCurrentIpConfigInfo(Kernel::HLERequestContext& ctx) {
494 rb.PushRaw<IpConfigInfo>(ip_config_info); 495 rb.PushRaw<IpConfigInfo>(ip_config_info);
495} 496}
496 497
497void IGeneralService::IsWirelessCommunicationEnabled(Kernel::HLERequestContext& ctx) { 498void IGeneralService::IsWirelessCommunicationEnabled(HLERequestContext& ctx) {
498 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 499 LOG_WARNING(Service_NIFM, "(STUBBED) called");
499 500
500 IPC::ResponseBuilder rb{ctx, 3}; 501 IPC::ResponseBuilder rb{ctx, 3};
@@ -502,7 +503,7 @@ void IGeneralService::IsWirelessCommunicationEnabled(Kernel::HLERequestContext&
502 rb.Push<u8>(1); 503 rb.Push<u8>(1);
503} 504}
504 505
505void IGeneralService::GetInternetConnectionStatus(Kernel::HLERequestContext& ctx) { 506void IGeneralService::GetInternetConnectionStatus(HLERequestContext& ctx) {
506 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 507 LOG_WARNING(Service_NIFM, "(STUBBED) called");
507 508
508 struct Output { 509 struct Output {
@@ -519,7 +520,7 @@ void IGeneralService::GetInternetConnectionStatus(Kernel::HLERequestContext& ctx
519 rb.PushRaw(out); 520 rb.PushRaw(out);
520} 521}
521 522
522void IGeneralService::IsEthernetCommunicationEnabled(Kernel::HLERequestContext& ctx) { 523void IGeneralService::IsEthernetCommunicationEnabled(HLERequestContext& ctx) {
523 LOG_WARNING(Service_NIFM, "(STUBBED) called"); 524 LOG_WARNING(Service_NIFM, "(STUBBED) called");
524 525
525 IPC::ResponseBuilder rb{ctx, 3}; 526 IPC::ResponseBuilder rb{ctx, 3};
@@ -531,7 +532,7 @@ void IGeneralService::IsEthernetCommunicationEnabled(Kernel::HLERequestContext&
531 } 532 }
532} 533}
533 534
534void IGeneralService::IsAnyInternetRequestAccepted(Kernel::HLERequestContext& ctx) { 535void IGeneralService::IsAnyInternetRequestAccepted(HLERequestContext& ctx) {
535 LOG_ERROR(Service_NIFM, "(STUBBED) called"); 536 LOG_ERROR(Service_NIFM, "(STUBBED) called");
536 537
537 IPC::ResponseBuilder rb{ctx, 3}; 538 IPC::ResponseBuilder rb{ctx, 3};
@@ -609,7 +610,7 @@ public:
609 } 610 }
610 611
611private: 612private:
612 void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) { 613 void CreateGeneralServiceOld(HLERequestContext& ctx) {
613 LOG_DEBUG(Service_NIFM, "called"); 614 LOG_DEBUG(Service_NIFM, "called");
614 615
615 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 616 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -617,7 +618,7 @@ private:
617 rb.PushIpcInterface<IGeneralService>(system); 618 rb.PushIpcInterface<IGeneralService>(system);
618 } 619 }
619 620
620 void CreateGeneralService(Kernel::HLERequestContext& ctx) { 621 void CreateGeneralService(HLERequestContext& ctx) {
621 LOG_DEBUG(Service_NIFM, "called"); 622 LOG_DEBUG(Service_NIFM, "called");
622 623
623 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 624 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -626,10 +627,16 @@ private:
626 } 627 }
627}; 628};
628 629
629void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 630void LoopProcess(Core::System& system) {
630 std::make_shared<NetworkInterface>("nifm:a", system)->InstallAsService(service_manager); 631 auto server_manager = std::make_unique<ServerManager>(system);
631 std::make_shared<NetworkInterface>("nifm:s", system)->InstallAsService(service_manager); 632
632 std::make_shared<NetworkInterface>("nifm:u", system)->InstallAsService(service_manager); 633 server_manager->RegisterNamedService("nifm:a",
634 std::make_shared<NetworkInterface>("nifm:a", system));
635 server_manager->RegisterNamedService("nifm:s",
636 std::make_shared<NetworkInterface>("nifm:s", system));
637 server_manager->RegisterNamedService("nifm:u",
638 std::make_shared<NetworkInterface>("nifm:u", system));
639 ServerManager::RunServer(std::move(server_manager));
633} 640}
634 641
635} // namespace Service::NIFM 642} // namespace Service::NIFM
diff --git a/src/core/hle/service/nifm/nifm.h b/src/core/hle/service/nifm/nifm.h
index 48161be28..9b20e6823 100644
--- a/src/core/hle/service/nifm/nifm.h
+++ b/src/core/hle/service/nifm/nifm.h
@@ -12,14 +12,9 @@ namespace Core {
12class System; 12class System;
13} 13}
14 14
15namespace Service::SM {
16class ServiceManager;
17}
18
19namespace Service::NIFM { 15namespace Service::NIFM {
20 16
21/// Registers all NIFM services with the specified service manager. 17void LoopProcess(Core::System& system);
22void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
23 18
24class IGeneralService final : public ServiceFramework<IGeneralService> { 19class IGeneralService final : public ServiceFramework<IGeneralService> {
25public: 20public:
@@ -27,18 +22,18 @@ public:
27 ~IGeneralService() override; 22 ~IGeneralService() override;
28 23
29private: 24private:
30 void GetClientId(Kernel::HLERequestContext& ctx); 25 void GetClientId(HLERequestContext& ctx);
31 void CreateScanRequest(Kernel::HLERequestContext& ctx); 26 void CreateScanRequest(HLERequestContext& ctx);
32 void CreateRequest(Kernel::HLERequestContext& ctx); 27 void CreateRequest(HLERequestContext& ctx);
33 void GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx); 28 void GetCurrentNetworkProfile(HLERequestContext& ctx);
34 void RemoveNetworkProfile(Kernel::HLERequestContext& ctx); 29 void RemoveNetworkProfile(HLERequestContext& ctx);
35 void GetCurrentIpAddress(Kernel::HLERequestContext& ctx); 30 void GetCurrentIpAddress(HLERequestContext& ctx);
36 void CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx); 31 void CreateTemporaryNetworkProfile(HLERequestContext& ctx);
37 void GetCurrentIpConfigInfo(Kernel::HLERequestContext& ctx); 32 void GetCurrentIpConfigInfo(HLERequestContext& ctx);
38 void IsWirelessCommunicationEnabled(Kernel::HLERequestContext& ctx); 33 void IsWirelessCommunicationEnabled(HLERequestContext& ctx);
39 void GetInternetConnectionStatus(Kernel::HLERequestContext& ctx); 34 void GetInternetConnectionStatus(HLERequestContext& ctx);
40 void IsEthernetCommunicationEnabled(Kernel::HLERequestContext& ctx); 35 void IsEthernetCommunicationEnabled(HLERequestContext& ctx);
41 void IsAnyInternetRequestAccepted(Kernel::HLERequestContext& ctx); 36 void IsAnyInternetRequestAccepted(HLERequestContext& ctx);
42 37
43 Network::RoomNetwork& network; 38 Network::RoomNetwork& network;
44}; 39};
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index 5a8a91e0b..42de87f9a 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -4,12 +4,12 @@
4#include <chrono> 4#include <chrono>
5#include <ctime> 5#include <ctime>
6#include "core/core.h" 6#include "core/core.h"
7#include "core/hle/ipc_helpers.h"
8#include "core/hle/kernel/k_event.h" 7#include "core/hle/kernel/k_event.h"
8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/kernel_helpers.h" 9#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/nim/nim.h" 10#include "core/hle/service/nim/nim.h"
11#include "core/hle/service/server_manager.h"
11#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
12#include "core/hle/service/sm/sm.h"
13 13
14namespace Service::NIM { 14namespace Service::NIM {
15 15
@@ -46,7 +46,7 @@ public:
46 } 46 }
47 47
48private: 48private:
49 void CreateAsyncInterface(Kernel::HLERequestContext& ctx) { 49 void CreateAsyncInterface(HLERequestContext& ctx) {
50 LOG_WARNING(Service_NIM, "(STUBBED) called"); 50 LOG_WARNING(Service_NIM, "(STUBBED) called");
51 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 51 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
52 rb.Push(ResultSuccess); 52 rb.Push(ResultSuccess);
@@ -68,7 +68,7 @@ public:
68 } 68 }
69 69
70private: 70private:
71 void CreateAccessorInterface(Kernel::HLERequestContext& ctx) { 71 void CreateAccessorInterface(HLERequestContext& ctx) {
72 LOG_WARNING(Service_NIM, "(STUBBED) called"); 72 LOG_WARNING(Service_NIM, "(STUBBED) called");
73 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 73 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
74 rb.Push(ResultSuccess); 74 rb.Push(ResultSuccess);
@@ -239,14 +239,14 @@ public:
239 } 239 }
240 240
241private: 241private:
242 void CreateServerInterface(Kernel::HLERequestContext& ctx) { 242 void CreateServerInterface(HLERequestContext& ctx) {
243 LOG_WARNING(Service_NIM, "(STUBBED) called"); 243 LOG_WARNING(Service_NIM, "(STUBBED) called");
244 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 244 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
245 rb.Push(ResultSuccess); 245 rb.Push(ResultSuccess);
246 rb.PushIpcInterface<IShopServiceAccessServer>(system); 246 rb.PushIpcInterface<IShopServiceAccessServer>(system);
247 } 247 }
248 248
249 void IsLargeResourceAvailable(Kernel::HLERequestContext& ctx) { 249 void IsLargeResourceAvailable(HLERequestContext& ctx) {
250 IPC::RequestParser rp{ctx}; 250 IPC::RequestParser rp{ctx};
251 251
252 const auto unknown{rp.Pop<u64>()}; 252 const auto unknown{rp.Pop<u64>()};
@@ -325,7 +325,7 @@ public:
325 } 325 }
326 326
327private: 327private:
328 void StartTask(Kernel::HLERequestContext& ctx) { 328 void StartTask(HLERequestContext& ctx) {
329 // No need to connect to the internet, just finish the task straight away. 329 // No need to connect to the internet, just finish the task straight away.
330 LOG_DEBUG(Service_NIM, "called"); 330 LOG_DEBUG(Service_NIM, "called");
331 finished_event->Signal(); 331 finished_event->Signal();
@@ -333,7 +333,7 @@ private:
333 rb.Push(ResultSuccess); 333 rb.Push(ResultSuccess);
334 } 334 }
335 335
336 void GetFinishNotificationEvent(Kernel::HLERequestContext& ctx) { 336 void GetFinishNotificationEvent(HLERequestContext& ctx) {
337 LOG_DEBUG(Service_NIM, "called"); 337 LOG_DEBUG(Service_NIM, "called");
338 338
339 IPC::ResponseBuilder rb{ctx, 2, 1}; 339 IPC::ResponseBuilder rb{ctx, 2, 1};
@@ -341,21 +341,21 @@ private:
341 rb.PushCopyObjects(finished_event->GetReadableEvent()); 341 rb.PushCopyObjects(finished_event->GetReadableEvent());
342 } 342 }
343 343
344 void GetResult(Kernel::HLERequestContext& ctx) { 344 void GetResult(HLERequestContext& ctx) {
345 LOG_DEBUG(Service_NIM, "called"); 345 LOG_DEBUG(Service_NIM, "called");
346 346
347 IPC::ResponseBuilder rb{ctx, 2}; 347 IPC::ResponseBuilder rb{ctx, 2};
348 rb.Push(ResultSuccess); 348 rb.Push(ResultSuccess);
349 } 349 }
350 350
351 void Cancel(Kernel::HLERequestContext& ctx) { 351 void Cancel(HLERequestContext& ctx) {
352 LOG_DEBUG(Service_NIM, "called"); 352 LOG_DEBUG(Service_NIM, "called");
353 finished_event->Clear(); 353 finished_event->Clear();
354 IPC::ResponseBuilder rb{ctx, 2}; 354 IPC::ResponseBuilder rb{ctx, 2};
355 rb.Push(ResultSuccess); 355 rb.Push(ResultSuccess);
356 } 356 }
357 357
358 void IsProcessing(Kernel::HLERequestContext& ctx) { 358 void IsProcessing(HLERequestContext& ctx) {
359 LOG_DEBUG(Service_NIM, "called"); 359 LOG_DEBUG(Service_NIM, "called");
360 360
361 IPC::ResponseBuilder rb{ctx, 3}; 361 IPC::ResponseBuilder rb{ctx, 3};
@@ -363,7 +363,7 @@ private:
363 rb.PushRaw<u32>(0); // We instantly process the request 363 rb.PushRaw<u32>(0); // We instantly process the request
364 } 364 }
365 365
366 void GetServerTime(Kernel::HLERequestContext& ctx) { 366 void GetServerTime(HLERequestContext& ctx) {
367 LOG_DEBUG(Service_NIM, "called"); 367 LOG_DEBUG(Service_NIM, "called");
368 368
369 const s64 server_time{std::chrono::duration_cast<std::chrono::seconds>( 369 const s64 server_time{std::chrono::duration_cast<std::chrono::seconds>(
@@ -394,7 +394,7 @@ public:
394 } 394 }
395 395
396private: 396private:
397 void OpenEnsureNetworkClockAvailabilityService(Kernel::HLERequestContext& ctx) { 397 void OpenEnsureNetworkClockAvailabilityService(HLERequestContext& ctx) {
398 LOG_DEBUG(Service_NIM, "called"); 398 LOG_DEBUG(Service_NIM, "called");
399 399
400 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 400 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -403,14 +403,14 @@ private:
403 } 403 }
404 404
405 // TODO(ogniK): Do we need these? 405 // TODO(ogniK): Do we need these?
406 void SuspendAutonomicTimeCorrection(Kernel::HLERequestContext& ctx) { 406 void SuspendAutonomicTimeCorrection(HLERequestContext& ctx) {
407 LOG_WARNING(Service_NIM, "(STUBBED) called"); 407 LOG_WARNING(Service_NIM, "(STUBBED) called");
408 408
409 IPC::ResponseBuilder rb{ctx, 2}; 409 IPC::ResponseBuilder rb{ctx, 2};
410 rb.Push(ResultSuccess); 410 rb.Push(ResultSuccess);
411 } 411 }
412 412
413 void ResumeAutonomicTimeCorrection(Kernel::HLERequestContext& ctx) { 413 void ResumeAutonomicTimeCorrection(HLERequestContext& ctx) {
414 LOG_WARNING(Service_NIM, "(STUBBED) called"); 414 LOG_WARNING(Service_NIM, "(STUBBED) called");
415 415
416 IPC::ResponseBuilder rb{ctx, 2}; 416 IPC::ResponseBuilder rb{ctx, 2};
@@ -418,11 +418,14 @@ private:
418 } 418 }
419}; 419};
420 420
421void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 421void LoopProcess(Core::System& system) {
422 std::make_shared<NIM>(system)->InstallAsService(sm); 422 auto server_manager = std::make_unique<ServerManager>(system);
423 std::make_shared<NIM_ECA>(system)->InstallAsService(sm); 423
424 std::make_shared<NIM_SHP>(system)->InstallAsService(sm); 424 server_manager->RegisterNamedService("nim", std::make_shared<NIM>(system));
425 std::make_shared<NTC>(system)->InstallAsService(sm); 425 server_manager->RegisterNamedService("nim:eca", std::make_shared<NIM_ECA>(system));
426 server_manager->RegisterNamedService("nim:shp", std::make_shared<NIM_SHP>(system));
427 server_manager->RegisterNamedService("ntc", std::make_shared<NTC>(system));
428 ServerManager::RunServer(std::move(server_manager));
426} 429}
427 430
428} // namespace Service::NIM 431} // namespace Service::NIM
diff --git a/src/core/hle/service/nim/nim.h b/src/core/hle/service/nim/nim.h
index 8f6ff28e8..e7d599908 100644
--- a/src/core/hle/service/nim/nim.h
+++ b/src/core/hle/service/nim/nim.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::NIM { 10namespace Service::NIM {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::NIM 14} // namespace Service::NIM
diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp
index 8133711c2..a162e5c54 100644
--- a/src/core/hle/service/npns/npns.cpp
+++ b/src/core/hle/service/npns/npns.cpp
@@ -4,8 +4,8 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/npns/npns.h" 6#include "core/hle/service/npns/npns.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::NPNS { 10namespace Service::NPNS {
11 11
@@ -94,9 +94,12 @@ public:
94 } 94 }
95}; 95};
96 96
97void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 97void LoopProcess(Core::System& system) {
98 std::make_shared<NPNS_S>(system)->InstallAsService(sm); 98 auto server_manager = std::make_unique<ServerManager>(system);
99 std::make_shared<NPNS_U>(system)->InstallAsService(sm); 99
100 server_manager->RegisterNamedService("npns:s", std::make_shared<NPNS_S>(system));
101 server_manager->RegisterNamedService("npns:u", std::make_shared<NPNS_U>(system));
102 ServerManager::RunServer(std::move(server_manager));
100} 103}
101 104
102} // namespace Service::NPNS 105} // namespace Service::NPNS
diff --git a/src/core/hle/service/npns/npns.h b/src/core/hle/service/npns/npns.h
index 84e6ec437..0019fca76 100644
--- a/src/core/hle/service/npns/npns.h
+++ b/src/core/hle/service/npns/npns.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::NPNS { 10namespace Service::NPNS {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::NPNS 14} // namespace Service::NPNS
diff --git a/src/core/hle/service/ns/errors.h b/src/core/hle/service/ns/errors.h
index 8a7621798..16d2ea6f7 100644
--- a/src/core/hle/service/ns/errors.h
+++ b/src/core/hle/service/ns/errors.h
@@ -7,5 +7,6 @@
7 7
8namespace Service::NS { 8namespace Service::NS {
9 9
10constexpr Result ERR_APPLICATION_LANGUAGE_NOT_FOUND{ErrorModule::NS, 300}; 10constexpr Result ResultApplicationLanguageNotFound{ErrorModule::NS, 300};
11} \ No newline at end of file 11
12}
diff --git a/src/core/hle/service/ns/iplatform_service_manager.cpp b/src/core/hle/service/ns/iplatform_service_manager.cpp
index 1fab2f0dd..cd2705881 100644
--- a/src/core/hle/service/ns/iplatform_service_manager.cpp
+++ b/src/core/hle/service/ns/iplatform_service_manager.cpp
@@ -15,11 +15,11 @@
15#include "core/file_sys/registered_cache.h" 15#include "core/file_sys/registered_cache.h"
16#include "core/file_sys/romfs.h" 16#include "core/file_sys/romfs.h"
17#include "core/file_sys/system_archive/system_archive.h" 17#include "core/file_sys/system_archive/system_archive.h"
18#include "core/hle/ipc_helpers.h"
19#include "core/hle/kernel/k_shared_memory.h" 18#include "core/hle/kernel/k_shared_memory.h"
20#include "core/hle/kernel/kernel.h" 19#include "core/hle/kernel/kernel.h"
21#include "core/hle/kernel/physical_memory.h" 20#include "core/hle/kernel/physical_memory.h"
22#include "core/hle/service/filesystem/filesystem.h" 21#include "core/hle/service/filesystem/filesystem.h"
22#include "core/hle/service/ipc_helpers.h"
23#include "core/hle/service/ns/iplatform_service_manager.h" 23#include "core/hle/service/ns/iplatform_service_manager.h"
24 24
25namespace Service::NS { 25namespace Service::NS {
@@ -208,7 +208,7 @@ IPlatformServiceManager::IPlatformServiceManager(Core::System& system_, const ch
208 208
209IPlatformServiceManager::~IPlatformServiceManager() = default; 209IPlatformServiceManager::~IPlatformServiceManager() = default;
210 210
211void IPlatformServiceManager::RequestLoad(Kernel::HLERequestContext& ctx) { 211void IPlatformServiceManager::RequestLoad(HLERequestContext& ctx) {
212 IPC::RequestParser rp{ctx}; 212 IPC::RequestParser rp{ctx};
213 const u32 shared_font_type{rp.Pop<u32>()}; 213 const u32 shared_font_type{rp.Pop<u32>()};
214 // Games don't call this so all fonts should be loaded 214 // Games don't call this so all fonts should be loaded
@@ -218,7 +218,7 @@ void IPlatformServiceManager::RequestLoad(Kernel::HLERequestContext& ctx) {
218 rb.Push(ResultSuccess); 218 rb.Push(ResultSuccess);
219} 219}
220 220
221void IPlatformServiceManager::GetLoadState(Kernel::HLERequestContext& ctx) { 221void IPlatformServiceManager::GetLoadState(HLERequestContext& ctx) {
222 IPC::RequestParser rp{ctx}; 222 IPC::RequestParser rp{ctx};
223 const u32 font_id{rp.Pop<u32>()}; 223 const u32 font_id{rp.Pop<u32>()};
224 LOG_DEBUG(Service_NS, "called, font_id={}", font_id); 224 LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
@@ -228,7 +228,7 @@ void IPlatformServiceManager::GetLoadState(Kernel::HLERequestContext& ctx) {
228 rb.Push<u32>(static_cast<u32>(LoadState::Done)); 228 rb.Push<u32>(static_cast<u32>(LoadState::Done));
229} 229}
230 230
231void IPlatformServiceManager::GetSize(Kernel::HLERequestContext& ctx) { 231void IPlatformServiceManager::GetSize(HLERequestContext& ctx) {
232 IPC::RequestParser rp{ctx}; 232 IPC::RequestParser rp{ctx};
233 const u32 font_id{rp.Pop<u32>()}; 233 const u32 font_id{rp.Pop<u32>()};
234 LOG_DEBUG(Service_NS, "called, font_id={}", font_id); 234 LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
@@ -238,7 +238,7 @@ void IPlatformServiceManager::GetSize(Kernel::HLERequestContext& ctx) {
238 rb.Push<u32>(impl->GetSharedFontRegion(font_id).size); 238 rb.Push<u32>(impl->GetSharedFontRegion(font_id).size);
239} 239}
240 240
241void IPlatformServiceManager::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) { 241void IPlatformServiceManager::GetSharedMemoryAddressOffset(HLERequestContext& ctx) {
242 IPC::RequestParser rp{ctx}; 242 IPC::RequestParser rp{ctx};
243 const u32 font_id{rp.Pop<u32>()}; 243 const u32 font_id{rp.Pop<u32>()};
244 LOG_DEBUG(Service_NS, "called, font_id={}", font_id); 244 LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
@@ -248,7 +248,7 @@ void IPlatformServiceManager::GetSharedMemoryAddressOffset(Kernel::HLERequestCon
248 rb.Push<u32>(impl->GetSharedFontRegion(font_id).offset); 248 rb.Push<u32>(impl->GetSharedFontRegion(font_id).offset);
249} 249}
250 250
251void IPlatformServiceManager::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { 251void IPlatformServiceManager::GetSharedMemoryNativeHandle(HLERequestContext& ctx) {
252 // Map backing memory for the font data 252 // Map backing memory for the font data
253 LOG_DEBUG(Service_NS, "called"); 253 LOG_DEBUG(Service_NS, "called");
254 254
@@ -261,7 +261,7 @@ void IPlatformServiceManager::GetSharedMemoryNativeHandle(Kernel::HLERequestCont
261 rb.PushCopyObjects(&kernel.GetFontSharedMem()); 261 rb.PushCopyObjects(&kernel.GetFontSharedMem());
262} 262}
263 263
264void IPlatformServiceManager::GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx) { 264void IPlatformServiceManager::GetSharedFontInOrderOfPriority(HLERequestContext& ctx) {
265 IPC::RequestParser rp{ctx}; 265 IPC::RequestParser rp{ctx};
266 const u64 language_code{rp.Pop<u64>()}; // TODO(ogniK): Find out what this is used for 266 const u64 language_code{rp.Pop<u64>()}; // TODO(ogniK): Find out what this is used for
267 LOG_DEBUG(Service_NS, "called, language_code={:X}", language_code); 267 LOG_DEBUG(Service_NS, "called, language_code={:X}", language_code);
diff --git a/src/core/hle/service/ns/iplatform_service_manager.h b/src/core/hle/service/ns/iplatform_service_manager.h
index ed6eda89f..03071e02b 100644
--- a/src/core/hle/service/ns/iplatform_service_manager.h
+++ b/src/core/hle/service/ns/iplatform_service_manager.h
@@ -42,12 +42,12 @@ public:
42 ~IPlatformServiceManager() override; 42 ~IPlatformServiceManager() override;
43 43
44private: 44private:
45 void RequestLoad(Kernel::HLERequestContext& ctx); 45 void RequestLoad(HLERequestContext& ctx);
46 void GetLoadState(Kernel::HLERequestContext& ctx); 46 void GetLoadState(HLERequestContext& ctx);
47 void GetSize(Kernel::HLERequestContext& ctx); 47 void GetSize(HLERequestContext& ctx);
48 void GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx); 48 void GetSharedMemoryAddressOffset(HLERequestContext& ctx);
49 void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx); 49 void GetSharedMemoryNativeHandle(HLERequestContext& ctx);
50 void GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx); 50 void GetSharedFontInOrderOfPriority(HLERequestContext& ctx);
51 51
52 struct Impl; 52 struct Impl;
53 std::unique_ptr<Impl> impl; 53 std::unique_ptr<Impl> impl;
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index e53bdde52..376067a95 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -7,13 +7,14 @@
7#include "core/file_sys/control_metadata.h" 7#include "core/file_sys/control_metadata.h"
8#include "core/file_sys/patch_manager.h" 8#include "core/file_sys/patch_manager.h"
9#include "core/file_sys/vfs.h" 9#include "core/file_sys/vfs.h"
10#include "core/hle/ipc_helpers.h"
11#include "core/hle/service/glue/glue_manager.h" 10#include "core/hle/service/glue/glue_manager.h"
11#include "core/hle/service/ipc_helpers.h"
12#include "core/hle/service/ns/errors.h" 12#include "core/hle/service/ns/errors.h"
13#include "core/hle/service/ns/iplatform_service_manager.h" 13#include "core/hle/service/ns/iplatform_service_manager.h"
14#include "core/hle/service/ns/language.h" 14#include "core/hle/service/ns/language.h"
15#include "core/hle/service/ns/ns.h" 15#include "core/hle/service/ns/ns.h"
16#include "core/hle/service/ns/pdm_qry.h" 16#include "core/hle/service/ns/pdm_qry.h"
17#include "core/hle/service/server_manager.h"
17#include "core/hle/service/set/set.h" 18#include "core/hle/service/set/set.h"
18 19
19namespace Service::NS { 20namespace Service::NS {
@@ -328,7 +329,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
328 329
329IApplicationManagerInterface::~IApplicationManagerInterface() = default; 330IApplicationManagerInterface::~IApplicationManagerInterface() = default;
330 331
331void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestContext& ctx) { 332void IApplicationManagerInterface::GetApplicationControlData(HLERequestContext& ctx) {
332 IPC::RequestParser rp{ctx}; 333 IPC::RequestParser rp{ctx};
333 const auto flag = rp.PopRaw<u64>(); 334 const auto flag = rp.PopRaw<u64>();
334 LOG_DEBUG(Service_NS, "called with flag={:016X}", flag); 335 LOG_DEBUG(Service_NS, "called with flag={:016X}", flag);
@@ -387,7 +388,7 @@ void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestC
387 rb.Push<u32>(static_cast<u32>(out.size())); 388 rb.Push<u32>(static_cast<u32>(out.size()));
388} 389}
389 390
390void IApplicationManagerInterface::GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx) { 391void IApplicationManagerInterface::GetApplicationDesiredLanguage(HLERequestContext& ctx) {
391 IPC::RequestParser rp{ctx}; 392 IPC::RequestParser rp{ctx};
392 const auto supported_languages = rp.Pop<u32>(); 393 const auto supported_languages = rp.Pop<u32>();
393 394
@@ -415,14 +416,14 @@ ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage(
415 if (application_language == std::nullopt) { 416 if (application_language == std::nullopt) {
416 LOG_ERROR(Service_NS, "Could not convert application language! language_code={}", 417 LOG_ERROR(Service_NS, "Could not convert application language! language_code={}",
417 language_code); 418 language_code);
418 return ERR_APPLICATION_LANGUAGE_NOT_FOUND; 419 return Service::NS::ResultApplicationLanguageNotFound;
419 } 420 }
420 const auto priority_list = GetApplicationLanguagePriorityList(*application_language); 421 const auto priority_list = GetApplicationLanguagePriorityList(*application_language);
421 if (!priority_list) { 422 if (!priority_list) {
422 LOG_ERROR(Service_NS, 423 LOG_ERROR(Service_NS,
423 "Could not find application language priorities! application_language={}", 424 "Could not find application language priorities! application_language={}",
424 *application_language); 425 *application_language);
425 return ERR_APPLICATION_LANGUAGE_NOT_FOUND; 426 return Service::NS::ResultApplicationLanguageNotFound;
426 } 427 }
427 428
428 // Try to find a valid language. 429 // Try to find a valid language.
@@ -435,11 +436,11 @@ ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage(
435 436
436 LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}", 437 LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}",
437 supported_languages); 438 supported_languages);
438 return ERR_APPLICATION_LANGUAGE_NOT_FOUND; 439 return Service::NS::ResultApplicationLanguageNotFound;
439} 440}
440 441
441void IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode( 442void IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode(
442 Kernel::HLERequestContext& ctx) { 443 HLERequestContext& ctx) {
443 IPC::RequestParser rp{ctx}; 444 IPC::RequestParser rp{ctx};
444 const auto application_language = rp.Pop<u8>(); 445 const auto application_language = rp.Pop<u8>();
445 446
@@ -460,7 +461,7 @@ ResultVal<u64> IApplicationManagerInterface::ConvertApplicationLanguageToLanguag
460 ConvertToLanguageCode(static_cast<ApplicationLanguage>(application_language)); 461 ConvertToLanguageCode(static_cast<ApplicationLanguage>(application_language));
461 if (language_code == std::nullopt) { 462 if (language_code == std::nullopt) {
462 LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language); 463 LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language);
463 return ERR_APPLICATION_LANGUAGE_NOT_FOUND; 464 return Service::NS::ResultApplicationLanguageNotFound;
464 } 465 }
465 466
466 return static_cast<u64>(*language_code); 467 return static_cast<u64>(*language_code);
@@ -603,8 +604,7 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
603 604
604IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default; 605IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default;
605 606
606void IReadOnlyApplicationControlDataInterface::GetApplicationControlData( 607void IReadOnlyApplicationControlDataInterface::GetApplicationControlData(HLERequestContext& ctx) {
607 Kernel::HLERequestContext& ctx) {
608 enum class ApplicationControlSource : u8 { 608 enum class ApplicationControlSource : u8 {
609 CacheOnly, 609 CacheOnly,
610 Storage, 610 Storage,
@@ -752,7 +752,7 @@ public:
752 } 752 }
753 753
754private: 754private:
755 void OpenSystemUpdateControl(Kernel::HLERequestContext& ctx) { 755 void OpenSystemUpdateControl(HLERequestContext& ctx) {
756 LOG_DEBUG(Service_NS, "called"); 756 LOG_DEBUG(Service_NS, "called");
757 757
758 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 758 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -776,7 +776,7 @@ public:
776 } 776 }
777 777
778private: 778private:
779 void NeedsUpdateVulnerability(Kernel::HLERequestContext& ctx) { 779 void NeedsUpdateVulnerability(HLERequestContext& ctx) {
780 LOG_WARNING(Service_NS, "(STUBBED) called"); 780 LOG_WARNING(Service_NS, "(STUBBED) called");
781 781
782 IPC::ResponseBuilder rb{ctx, 3}; 782 IPC::ResponseBuilder rb{ctx, 3};
@@ -785,23 +785,26 @@ private:
785 } 785 }
786}; 786};
787 787
788void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 788void LoopProcess(Core::System& system) {
789 789 auto server_manager = std::make_unique<ServerManager>(system);
790 std::make_shared<NS>("ns:am2", system)->InstallAsService(service_manager); 790
791 std::make_shared<NS>("ns:ec", system)->InstallAsService(service_manager); 791 server_manager->RegisterNamedService("ns:am2", std::make_shared<NS>("ns:am2", system));
792 std::make_shared<NS>("ns:rid", system)->InstallAsService(service_manager); 792 server_manager->RegisterNamedService("ns:ec", std::make_shared<NS>("ns:ec", system));
793 std::make_shared<NS>("ns:rt", system)->InstallAsService(service_manager); 793 server_manager->RegisterNamedService("ns:rid", std::make_shared<NS>("ns:rid", system));
794 std::make_shared<NS>("ns:web", system)->InstallAsService(service_manager); 794 server_manager->RegisterNamedService("ns:rt", std::make_shared<NS>("ns:rt", system));
795 std::make_shared<NS>("ns:ro", system)->InstallAsService(service_manager); 795 server_manager->RegisterNamedService("ns:web", std::make_shared<NS>("ns:web", system));
796 796 server_manager->RegisterNamedService("ns:ro", std::make_shared<NS>("ns:ro", system));
797 std::make_shared<NS_DEV>(system)->InstallAsService(service_manager); 797
798 std::make_shared<NS_SU>(system)->InstallAsService(service_manager); 798 server_manager->RegisterNamedService("ns:dev", std::make_shared<NS_DEV>(system));
799 std::make_shared<NS_VM>(system)->InstallAsService(service_manager); 799 server_manager->RegisterNamedService("ns:su", std::make_shared<NS_SU>(system));
800 800 server_manager->RegisterNamedService("ns:vm", std::make_shared<NS_VM>(system));
801 std::make_shared<PDM_QRY>(system)->InstallAsService(service_manager); 801 server_manager->RegisterNamedService("pdm:qry", std::make_shared<PDM_QRY>(system));
802 802
803 std::make_shared<IPlatformServiceManager>(system, "pl:s")->InstallAsService(service_manager); 803 server_manager->RegisterNamedService("pl:s",
804 std::make_shared<IPlatformServiceManager>(system, "pl:u")->InstallAsService(service_manager); 804 std::make_shared<IPlatformServiceManager>(system, "pl:s"));
805 server_manager->RegisterNamedService("pl:u",
806 std::make_shared<IPlatformServiceManager>(system, "pl:u"));
807 ServerManager::RunServer(std::move(server_manager));
805} 808}
806 809
807} // namespace Service::NS 810} // namespace Service::NS
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h
index 9c18e935c..203388e1f 100644
--- a/src/core/hle/service/ns/ns.h
+++ b/src/core/hle/service/ns/ns.h
@@ -32,9 +32,9 @@ public:
32 ResultVal<u64> ConvertApplicationLanguageToLanguageCode(u8 application_language); 32 ResultVal<u64> ConvertApplicationLanguageToLanguageCode(u8 application_language);
33 33
34private: 34private:
35 void GetApplicationControlData(Kernel::HLERequestContext& ctx); 35 void GetApplicationControlData(HLERequestContext& ctx);
36 void GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx); 36 void GetApplicationDesiredLanguage(HLERequestContext& ctx);
37 void ConvertApplicationLanguageToLanguageCode(Kernel::HLERequestContext& ctx); 37 void ConvertApplicationLanguageToLanguageCode(HLERequestContext& ctx);
38}; 38};
39 39
40class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> { 40class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
@@ -80,7 +80,7 @@ public:
80 ~IReadOnlyApplicationControlDataInterface() override; 80 ~IReadOnlyApplicationControlDataInterface() override;
81 81
82private: 82private:
83 void GetApplicationControlData(Kernel::HLERequestContext& ctx); 83 void GetApplicationControlData(HLERequestContext& ctx);
84}; 84};
85 85
86class NS final : public ServiceFramework<NS> { 86class NS final : public ServiceFramework<NS> {
@@ -92,7 +92,7 @@ public:
92 92
93private: 93private:
94 template <typename T, typename... Args> 94 template <typename T, typename... Args>
95 void PushInterface(Kernel::HLERequestContext& ctx) { 95 void PushInterface(HLERequestContext& ctx) {
96 LOG_DEBUG(Service_NS, "called"); 96 LOG_DEBUG(Service_NS, "called");
97 97
98 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 98 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -100,7 +100,7 @@ private:
100 rb.PushIpcInterface<T>(system); 100 rb.PushIpcInterface<T>(system);
101 } 101 }
102 102
103 void PushIApplicationManagerInterface(Kernel::HLERequestContext& ctx) { 103 void PushIApplicationManagerInterface(HLERequestContext& ctx) {
104 LOG_DEBUG(Service_NS, "called"); 104 LOG_DEBUG(Service_NS, "called");
105 105
106 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 106 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -110,15 +110,14 @@ private:
110 110
111 template <typename T, typename... Args> 111 template <typename T, typename... Args>
112 std::shared_ptr<T> GetInterface(Args&&... args) const { 112 std::shared_ptr<T> GetInterface(Args&&... args) const {
113 static_assert(std::is_base_of_v<Kernel::SessionRequestHandler, T>, 113 static_assert(std::is_base_of_v<SessionRequestHandler, T>,
114 "Not a base of ServiceFrameworkBase"); 114 "Not a base of ServiceFrameworkBase");
115 115
116 return std::make_shared<T>(std::forward<Args>(args)...); 116 return std::make_shared<T>(std::forward<Args>(args)...);
117 } 117 }
118}; 118};
119 119
120/// Registers all NS services with the specified service manager. 120void LoopProcess(Core::System& system);
121void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
122 121
123} // namespace NS 122} // namespace NS
124} // namespace Service 123} // namespace Service
diff --git a/src/core/hle/service/ns/pdm_qry.cpp b/src/core/hle/service/ns/pdm_qry.cpp
index aac8f573f..ce0ee30e0 100644
--- a/src/core/hle/service/ns/pdm_qry.cpp
+++ b/src/core/hle/service/ns/pdm_qry.cpp
@@ -5,7 +5,7 @@
5 5
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "common/uuid.h" 7#include "common/uuid.h"
8#include "core/hle/ipc_helpers.h" 8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/ns/pdm_qry.h" 9#include "core/hle/service/ns/pdm_qry.h"
10#include "core/hle/service/service.h" 10#include "core/hle/service/service.h"
11 11
@@ -42,7 +42,7 @@ PDM_QRY::PDM_QRY(Core::System& system_) : ServiceFramework{system_, "pdm:qry"} {
42 42
43PDM_QRY::~PDM_QRY() = default; 43PDM_QRY::~PDM_QRY() = default;
44 44
45void PDM_QRY::QueryPlayStatisticsByApplicationIdAndUserAccountId(Kernel::HLERequestContext& ctx) { 45void PDM_QRY::QueryPlayStatisticsByApplicationIdAndUserAccountId(HLERequestContext& ctx) {
46 IPC::RequestParser rp{ctx}; 46 IPC::RequestParser rp{ctx};
47 const auto unknown = rp.Pop<bool>(); 47 const auto unknown = rp.Pop<bool>();
48 rp.Pop<u8>(); // Padding 48 rp.Pop<u8>(); // Padding
diff --git a/src/core/hle/service/ns/pdm_qry.h b/src/core/hle/service/ns/pdm_qry.h
index abcc3bef3..c98e01660 100644
--- a/src/core/hle/service/ns/pdm_qry.h
+++ b/src/core/hle/service/ns/pdm_qry.h
@@ -26,7 +26,7 @@ public:
26 ~PDM_QRY() override; 26 ~PDM_QRY() override;
27 27
28private: 28private:
29 void QueryPlayStatisticsByApplicationIdAndUserAccountId(Kernel::HLERequestContext& ctx); 29 void QueryPlayStatisticsByApplicationIdAndUserAccountId(HLERequestContext& ctx);
30}; 30};
31 31
32} // namespace Service::NS 32} // namespace Service::NS
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
index 81bd7960a..bcd0e3ed5 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
@@ -8,8 +8,8 @@
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "common/math_util.h" 9#include "common/math_util.h"
10#include "core/hle/service/nvdrv/devices/nvdevice.h" 10#include "core/hle/service/nvdrv/devices/nvdevice.h"
11#include "core/hle/service/nvflinger/buffer_transform_flags.h" 11#include "core/hle/service/nvnflinger/buffer_transform_flags.h"
12#include "core/hle/service/nvflinger/pixel_format.h" 12#include "core/hle/service/nvnflinger/pixel_format.h"
13 13
14namespace Service::Nvidia::NvCore { 14namespace Service::Nvidia::NvCore {
15class Container; 15class Container;
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 52d27e755..3d774eec4 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -6,8 +6,8 @@
6 6
7#include <fmt/format.h> 7#include <fmt/format.h>
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/ipc_helpers.h"
10#include "core/hle/kernel/k_event.h" 9#include "core/hle/kernel/k_event.h"
10#include "core/hle/service/ipc_helpers.h"
11#include "core/hle/service/nvdrv/core/container.h" 11#include "core/hle/service/nvdrv/core/container.h"
12#include "core/hle/service/nvdrv/devices/nvdevice.h" 12#include "core/hle/service/nvdrv/devices/nvdevice.h"
13#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" 13#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
@@ -23,7 +23,8 @@
23#include "core/hle/service/nvdrv/nvdrv.h" 23#include "core/hle/service/nvdrv/nvdrv.h"
24#include "core/hle/service/nvdrv/nvdrv_interface.h" 24#include "core/hle/service/nvdrv/nvdrv_interface.h"
25#include "core/hle/service/nvdrv/nvmemp.h" 25#include "core/hle/service/nvdrv/nvmemp.h"
26#include "core/hle/service/nvflinger/nvflinger.h" 26#include "core/hle/service/nvnflinger/nvnflinger.h"
27#include "core/hle/service/server_manager.h"
27#include "video_core/gpu.h" 28#include "video_core/gpu.h"
28 29
29namespace Service::Nvidia { 30namespace Service::Nvidia {
@@ -41,15 +42,19 @@ void EventInterface::FreeEvent(Kernel::KEvent* event) {
41 module.service_context.CloseEvent(event); 42 module.service_context.CloseEvent(event);
42} 43}
43 44
44void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, 45void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) {
45 Core::System& system) { 46 auto server_manager = std::make_unique<ServerManager>(system);
46 auto module_ = std::make_shared<Module>(system); 47 auto module = std::make_shared<Module>(system);
47 std::make_shared<NVDRV>(system, module_, "nvdrv")->InstallAsService(service_manager); 48 server_manager->RegisterNamedService("nvdrv", std::make_shared<NVDRV>(system, module, "nvdrv"));
48 std::make_shared<NVDRV>(system, module_, "nvdrv:a")->InstallAsService(service_manager); 49 server_manager->RegisterNamedService("nvdrv:a",
49 std::make_shared<NVDRV>(system, module_, "nvdrv:s")->InstallAsService(service_manager); 50 std::make_shared<NVDRV>(system, module, "nvdrv:a"));
50 std::make_shared<NVDRV>(system, module_, "nvdrv:t")->InstallAsService(service_manager); 51 server_manager->RegisterNamedService("nvdrv:s",
51 std::make_shared<NVMEMP>(system)->InstallAsService(service_manager); 52 std::make_shared<NVDRV>(system, module, "nvdrv:s"));
52 nvflinger.SetNVDrvInstance(module_); 53 server_manager->RegisterNamedService("nvdrv:t",
54 std::make_shared<NVDRV>(system, module, "nvdrv:t"));
55 server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system));
56 nvnflinger.SetNVDrvInstance(module);
57 ServerManager::RunServer(std::move(server_manager));
53} 58}
54 59
55Module::Module(Core::System& system) 60Module::Module(Core::System& system)
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index b09b6e585..668be742b 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -16,7 +16,7 @@
16#include "core/hle/service/kernel_helpers.h" 16#include "core/hle/service/kernel_helpers.h"
17#include "core/hle/service/nvdrv/core/container.h" 17#include "core/hle/service/nvdrv/core/container.h"
18#include "core/hle/service/nvdrv/nvdata.h" 18#include "core/hle/service/nvdrv/nvdata.h"
19#include "core/hle/service/nvflinger/ui/fence.h" 19#include "core/hle/service/nvnflinger/ui/fence.h"
20#include "core/hle/service/service.h" 20#include "core/hle/service/service.h"
21 21
22namespace Core { 22namespace Core {
@@ -27,8 +27,8 @@ namespace Kernel {
27class KEvent; 27class KEvent;
28} 28}
29 29
30namespace Service::NVFlinger { 30namespace Service::Nvnflinger {
31class NVFlinger; 31class Nvnflinger;
32} 32}
33 33
34namespace Service::Nvidia { 34namespace Service::Nvidia {
@@ -95,7 +95,7 @@ public:
95 95
96private: 96private:
97 friend class EventInterface; 97 friend class EventInterface;
98 friend class Service::NVFlinger::NVFlinger; 98 friend class Service::Nvnflinger::Nvnflinger;
99 99
100 /// Manages syncpoints on the host 100 /// Manages syncpoints on the host
101 NvCore::Container container; 101 NvCore::Container container;
@@ -114,8 +114,6 @@ private:
114 std::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders; 114 std::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders;
115}; 115};
116 116
117/// Registers all NVDRV services with the specified service manager. 117void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system);
118void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
119 Core::System& system);
120 118
121} // namespace Service::Nvidia 119} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
index edbdfee43..d010a1e03 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
@@ -5,16 +5,16 @@
5#include <cinttypes> 5#include <cinttypes>
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core.h" 7#include "core/core.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/k_event.h" 8#include "core/hle/kernel/k_event.h"
10#include "core/hle/kernel/k_readable_event.h" 9#include "core/hle/kernel/k_readable_event.h"
10#include "core/hle/service/ipc_helpers.h"
11#include "core/hle/service/nvdrv/nvdata.h" 11#include "core/hle/service/nvdrv/nvdata.h"
12#include "core/hle/service/nvdrv/nvdrv.h" 12#include "core/hle/service/nvdrv/nvdrv.h"
13#include "core/hle/service/nvdrv/nvdrv_interface.h" 13#include "core/hle/service/nvdrv/nvdrv_interface.h"
14 14
15namespace Service::Nvidia { 15namespace Service::Nvidia {
16 16
17void NVDRV::Open(Kernel::HLERequestContext& ctx) { 17void NVDRV::Open(HLERequestContext& ctx) {
18 LOG_DEBUG(Service_NVDRV, "called"); 18 LOG_DEBUG(Service_NVDRV, "called");
19 IPC::ResponseBuilder rb{ctx, 4}; 19 IPC::ResponseBuilder rb{ctx, 4};
20 rb.Push(ResultSuccess); 20 rb.Push(ResultSuccess);
@@ -44,13 +44,13 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) {
44 rb.PushEnum(fd != INVALID_NVDRV_FD ? NvResult::Success : NvResult::FileOperationFailed); 44 rb.PushEnum(fd != INVALID_NVDRV_FD ? NvResult::Success : NvResult::FileOperationFailed);
45} 45}
46 46
47void NVDRV::ServiceError(Kernel::HLERequestContext& ctx, NvResult result) { 47void NVDRV::ServiceError(HLERequestContext& ctx, NvResult result) {
48 IPC::ResponseBuilder rb{ctx, 3}; 48 IPC::ResponseBuilder rb{ctx, 3};
49 rb.Push(ResultSuccess); 49 rb.Push(ResultSuccess);
50 rb.PushEnum(result); 50 rb.PushEnum(result);
51} 51}
52 52
53void NVDRV::Ioctl1(Kernel::HLERequestContext& ctx) { 53void NVDRV::Ioctl1(HLERequestContext& ctx) {
54 IPC::RequestParser rp{ctx}; 54 IPC::RequestParser rp{ctx};
55 const auto fd = rp.Pop<DeviceFD>(); 55 const auto fd = rp.Pop<DeviceFD>();
56 const auto command = rp.PopRaw<Ioctl>(); 56 const auto command = rp.PopRaw<Ioctl>();
@@ -76,7 +76,7 @@ void NVDRV::Ioctl1(Kernel::HLERequestContext& ctx) {
76 rb.PushEnum(nv_result); 76 rb.PushEnum(nv_result);
77} 77}
78 78
79void NVDRV::Ioctl2(Kernel::HLERequestContext& ctx) { 79void NVDRV::Ioctl2(HLERequestContext& ctx) {
80 IPC::RequestParser rp{ctx}; 80 IPC::RequestParser rp{ctx};
81 const auto fd = rp.Pop<DeviceFD>(); 81 const auto fd = rp.Pop<DeviceFD>();
82 const auto command = rp.PopRaw<Ioctl>(); 82 const auto command = rp.PopRaw<Ioctl>();
@@ -103,7 +103,7 @@ void NVDRV::Ioctl2(Kernel::HLERequestContext& ctx) {
103 rb.PushEnum(nv_result); 103 rb.PushEnum(nv_result);
104} 104}
105 105
106void NVDRV::Ioctl3(Kernel::HLERequestContext& ctx) { 106void NVDRV::Ioctl3(HLERequestContext& ctx) {
107 IPC::RequestParser rp{ctx}; 107 IPC::RequestParser rp{ctx};
108 const auto fd = rp.Pop<DeviceFD>(); 108 const auto fd = rp.Pop<DeviceFD>();
109 const auto command = rp.PopRaw<Ioctl>(); 109 const auto command = rp.PopRaw<Ioctl>();
@@ -131,7 +131,7 @@ void NVDRV::Ioctl3(Kernel::HLERequestContext& ctx) {
131 rb.PushEnum(nv_result); 131 rb.PushEnum(nv_result);
132} 132}
133 133
134void NVDRV::Close(Kernel::HLERequestContext& ctx) { 134void NVDRV::Close(HLERequestContext& ctx) {
135 LOG_DEBUG(Service_NVDRV, "called"); 135 LOG_DEBUG(Service_NVDRV, "called");
136 136
137 if (!is_initialized) { 137 if (!is_initialized) {
@@ -149,7 +149,7 @@ void NVDRV::Close(Kernel::HLERequestContext& ctx) {
149 rb.PushEnum(result); 149 rb.PushEnum(result);
150} 150}
151 151
152void NVDRV::Initialize(Kernel::HLERequestContext& ctx) { 152void NVDRV::Initialize(HLERequestContext& ctx) {
153 LOG_WARNING(Service_NVDRV, "(STUBBED) called"); 153 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
154 154
155 is_initialized = true; 155 is_initialized = true;
@@ -159,7 +159,7 @@ void NVDRV::Initialize(Kernel::HLERequestContext& ctx) {
159 rb.PushEnum(NvResult::Success); 159 rb.PushEnum(NvResult::Success);
160} 160}
161 161
162void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) { 162void NVDRV::QueryEvent(HLERequestContext& ctx) {
163 IPC::RequestParser rp{ctx}; 163 IPC::RequestParser rp{ctx};
164 const auto fd = rp.Pop<DeviceFD>(); 164 const auto fd = rp.Pop<DeviceFD>();
165 const auto event_id = rp.Pop<u32>(); 165 const auto event_id = rp.Pop<u32>();
@@ -187,7 +187,7 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
187 } 187 }
188} 188}
189 189
190void NVDRV::SetAruid(Kernel::HLERequestContext& ctx) { 190void NVDRV::SetAruid(HLERequestContext& ctx) {
191 IPC::RequestParser rp{ctx}; 191 IPC::RequestParser rp{ctx};
192 pid = rp.Pop<u64>(); 192 pid = rp.Pop<u64>();
193 LOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x{:X}", pid); 193 LOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x{:X}", pid);
@@ -197,14 +197,14 @@ void NVDRV::SetAruid(Kernel::HLERequestContext& ctx) {
197 rb.PushEnum(NvResult::Success); 197 rb.PushEnum(NvResult::Success);
198} 198}
199 199
200void NVDRV::SetGraphicsFirmwareMemoryMarginEnabled(Kernel::HLERequestContext& ctx) { 200void NVDRV::SetGraphicsFirmwareMemoryMarginEnabled(HLERequestContext& ctx) {
201 LOG_WARNING(Service_NVDRV, "(STUBBED) called"); 201 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
202 202
203 IPC::ResponseBuilder rb{ctx, 2}; 203 IPC::ResponseBuilder rb{ctx, 2};
204 rb.Push(ResultSuccess); 204 rb.Push(ResultSuccess);
205} 205}
206 206
207void NVDRV::GetStatus(Kernel::HLERequestContext& ctx) { 207void NVDRV::GetStatus(HLERequestContext& ctx) {
208 LOG_WARNING(Service_NVDRV, "(STUBBED) called"); 208 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
209 209
210 IPC::ResponseBuilder rb{ctx, 3}; 210 IPC::ResponseBuilder rb{ctx, 3};
@@ -212,7 +212,7 @@ void NVDRV::GetStatus(Kernel::HLERequestContext& ctx) {
212 rb.PushEnum(NvResult::Success); 212 rb.PushEnum(NvResult::Success);
213} 213}
214 214
215void NVDRV::DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx) { 215void NVDRV::DumpGraphicsMemoryInfo(HLERequestContext& ctx) {
216 // According to SwitchBrew, this has no inputs and no outputs, so effectively does nothing on 216 // According to SwitchBrew, this has no inputs and no outputs, so effectively does nothing on
217 // retail hardware. 217 // retail hardware.
218 LOG_DEBUG(Service_NVDRV, "called"); 218 LOG_DEBUG(Service_NVDRV, "called");
@@ -222,7 +222,7 @@ void NVDRV::DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx) {
222} 222}
223 223
224NVDRV::NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name) 224NVDRV::NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name)
225 : ServiceFramework{system_, name, ServiceThreadType::CreateNew}, nvdrv{std::move(nvdrv_)} { 225 : ServiceFramework{system_, name}, nvdrv{std::move(nvdrv_)} {
226 static const FunctionInfo functions[] = { 226 static const FunctionInfo functions[] = {
227 {0, &NVDRV::Open, "Open"}, 227 {0, &NVDRV::Open, "Open"},
228 {1, &NVDRV::Ioctl1, "Ioctl"}, 228 {1, &NVDRV::Ioctl1, "Ioctl"},
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h
index 5ac06ee30..881ea1a6b 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.h
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.h
@@ -15,19 +15,19 @@ public:
15 ~NVDRV() override; 15 ~NVDRV() override;
16 16
17private: 17private:
18 void Open(Kernel::HLERequestContext& ctx); 18 void Open(HLERequestContext& ctx);
19 void Ioctl1(Kernel::HLERequestContext& ctx); 19 void Ioctl1(HLERequestContext& ctx);
20 void Ioctl2(Kernel::HLERequestContext& ctx); 20 void Ioctl2(HLERequestContext& ctx);
21 void Ioctl3(Kernel::HLERequestContext& ctx); 21 void Ioctl3(HLERequestContext& ctx);
22 void Close(Kernel::HLERequestContext& ctx); 22 void Close(HLERequestContext& ctx);
23 void Initialize(Kernel::HLERequestContext& ctx); 23 void Initialize(HLERequestContext& ctx);
24 void QueryEvent(Kernel::HLERequestContext& ctx); 24 void QueryEvent(HLERequestContext& ctx);
25 void SetAruid(Kernel::HLERequestContext& ctx); 25 void SetAruid(HLERequestContext& ctx);
26 void SetGraphicsFirmwareMemoryMarginEnabled(Kernel::HLERequestContext& ctx); 26 void SetGraphicsFirmwareMemoryMarginEnabled(HLERequestContext& ctx);
27 void GetStatus(Kernel::HLERequestContext& ctx); 27 void GetStatus(HLERequestContext& ctx);
28 void DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx); 28 void DumpGraphicsMemoryInfo(HLERequestContext& ctx);
29 29
30 void ServiceError(Kernel::HLERequestContext& ctx, NvResult result); 30 void ServiceError(HLERequestContext& ctx, NvResult result);
31 31
32 std::shared_ptr<Module> nvdrv; 32 std::shared_ptr<Module> nvdrv;
33 33
diff --git a/src/core/hle/service/nvdrv/nvmemp.cpp b/src/core/hle/service/nvdrv/nvmemp.cpp
index e433580b1..fc10f6406 100644
--- a/src/core/hle/service/nvdrv/nvmemp.cpp
+++ b/src/core/hle/service/nvdrv/nvmemp.cpp
@@ -17,11 +17,11 @@ NVMEMP::NVMEMP(Core::System& system_) : ServiceFramework{system_, "nvmemp"} {
17 17
18NVMEMP::~NVMEMP() = default; 18NVMEMP::~NVMEMP() = default;
19 19
20void NVMEMP::Open(Kernel::HLERequestContext& ctx) { 20void NVMEMP::Open(HLERequestContext& ctx) {
21 UNIMPLEMENTED(); 21 UNIMPLEMENTED();
22} 22}
23 23
24void NVMEMP::GetAruid(Kernel::HLERequestContext& ctx) { 24void NVMEMP::GetAruid(HLERequestContext& ctx) {
25 UNIMPLEMENTED(); 25 UNIMPLEMENTED();
26} 26}
27 27
diff --git a/src/core/hle/service/nvdrv/nvmemp.h b/src/core/hle/service/nvdrv/nvmemp.h
index 3d4276327..85e3053a8 100644
--- a/src/core/hle/service/nvdrv/nvmemp.h
+++ b/src/core/hle/service/nvdrv/nvmemp.h
@@ -17,8 +17,8 @@ public:
17 ~NVMEMP() override; 17 ~NVMEMP() override;
18 18
19private: 19private:
20 void Open(Kernel::HLERequestContext& ctx); 20 void Open(HLERequestContext& ctx);
21 void GetAruid(Kernel::HLERequestContext& ctx); 21 void GetAruid(HLERequestContext& ctx);
22}; 22};
23 23
24} // namespace Service::Nvidia 24} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvflinger/binder.h b/src/core/hle/service/nvnflinger/binder.h
index 157333ff8..aef1477e3 100644
--- a/src/core/hle/service/nvflinger/binder.h
+++ b/src/core/hle/service/nvnflinger/binder.h
@@ -9,10 +9,13 @@
9#include "common/common_types.h" 9#include "common/common_types.h"
10 10
11namespace Kernel { 11namespace Kernel {
12class HLERequestContext;
13class KReadableEvent; 12class KReadableEvent;
14} // namespace Kernel 13} // namespace Kernel
15 14
15namespace Service {
16class HLERequestContext;
17}
18
16namespace Service::android { 19namespace Service::android {
17 20
18enum class TransactionId { 21enum class TransactionId {
@@ -35,8 +38,7 @@ enum class TransactionId {
35class IBinder { 38class IBinder {
36public: 39public:
37 virtual ~IBinder() = default; 40 virtual ~IBinder() = default;
38 virtual void Transact(Kernel::HLERequestContext& ctx, android::TransactionId code, 41 virtual void Transact(HLERequestContext& ctx, android::TransactionId code, u32 flags) = 0;
39 u32 flags) = 0;
40 virtual Kernel::KReadableEvent& GetNativeHandle() = 0; 42 virtual Kernel::KReadableEvent& GetNativeHandle() = 0;
41}; 43};
42 44
diff --git a/src/core/hle/service/nvflinger/buffer_item.h b/src/core/hle/service/nvnflinger/buffer_item.h
index f73dec4f1..7fd808f54 100644
--- a/src/core/hle/service/nvflinger/buffer_item.h
+++ b/src/core/hle/service/nvnflinger/buffer_item.h
@@ -10,8 +10,8 @@
10 10
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "common/math_util.h" 12#include "common/math_util.h"
13#include "core/hle/service/nvflinger/ui/fence.h" 13#include "core/hle/service/nvnflinger/ui/fence.h"
14#include "core/hle/service/nvflinger/window.h" 14#include "core/hle/service/nvnflinger/window.h"
15 15
16namespace Service::android { 16namespace Service::android {
17 17
diff --git a/src/core/hle/service/nvflinger/buffer_item_consumer.cpp b/src/core/hle/service/nvnflinger/buffer_item_consumer.cpp
index 152bb5bdf..cf151ea3a 100644
--- a/src/core/hle/service/nvflinger/buffer_item_consumer.cpp
+++ b/src/core/hle/service/nvnflinger/buffer_item_consumer.cpp
@@ -6,9 +6,9 @@
6 6
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "core/hle/service/nvflinger/buffer_item.h" 9#include "core/hle/service/nvnflinger/buffer_item.h"
10#include "core/hle/service/nvflinger/buffer_item_consumer.h" 10#include "core/hle/service/nvnflinger/buffer_item_consumer.h"
11#include "core/hle/service/nvflinger/buffer_queue_consumer.h" 11#include "core/hle/service/nvnflinger/buffer_queue_consumer.h"
12 12
13namespace Service::android { 13namespace Service::android {
14 14
@@ -25,7 +25,7 @@ Status BufferItemConsumer::AcquireBuffer(BufferItem* item, std::chrono::nanoseco
25 25
26 if (const auto status = AcquireBufferLocked(item, present_when); status != Status::NoError) { 26 if (const auto status = AcquireBufferLocked(item, present_when); status != Status::NoError) {
27 if (status != Status::NoBufferAvailable) { 27 if (status != Status::NoBufferAvailable) {
28 LOG_ERROR(Service_NVFlinger, "Failed to acquire buffer: {}", status); 28 LOG_ERROR(Service_Nvnflinger, "Failed to acquire buffer: {}", status);
29 } 29 }
30 return status; 30 return status;
31 } 31 }
@@ -44,12 +44,12 @@ Status BufferItemConsumer::ReleaseBuffer(const BufferItem& item, const Fence& re
44 44
45 if (const auto status = AddReleaseFenceLocked(item.buf, item.graphic_buffer, release_fence); 45 if (const auto status = AddReleaseFenceLocked(item.buf, item.graphic_buffer, release_fence);
46 status != Status::NoError) { 46 status != Status::NoError) {
47 LOG_ERROR(Service_NVFlinger, "Failed to add fence: {}", status); 47 LOG_ERROR(Service_Nvnflinger, "Failed to add fence: {}", status);
48 } 48 }
49 49
50 if (const auto status = ReleaseBufferLocked(item.buf, item.graphic_buffer); 50 if (const auto status = ReleaseBufferLocked(item.buf, item.graphic_buffer);
51 status != Status::NoError) { 51 status != Status::NoError) {
52 LOG_WARNING(Service_NVFlinger, "Failed to release buffer: {}", status); 52 LOG_WARNING(Service_Nvnflinger, "Failed to release buffer: {}", status);
53 return status; 53 return status;
54 } 54 }
55 55
diff --git a/src/core/hle/service/nvflinger/buffer_item_consumer.h b/src/core/hle/service/nvnflinger/buffer_item_consumer.h
index a5c655d9e..e0c6b3604 100644
--- a/src/core/hle/service/nvflinger/buffer_item_consumer.h
+++ b/src/core/hle/service/nvnflinger/buffer_item_consumer.h
@@ -10,8 +10,8 @@
10#include <memory> 10#include <memory>
11 11
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "core/hle/service/nvflinger/consumer_base.h" 13#include "core/hle/service/nvnflinger/consumer_base.h"
14#include "core/hle/service/nvflinger/status.h" 14#include "core/hle/service/nvnflinger/status.h"
15 15
16namespace Service::android { 16namespace Service::android {
17 17
diff --git a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp
index 0767e548d..51291539d 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp
+++ b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp
@@ -6,11 +6,11 @@
6 6
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "core/hle/service/nvdrv/core/nvmap.h" 8#include "core/hle/service/nvdrv/core/nvmap.h"
9#include "core/hle/service/nvflinger/buffer_item.h" 9#include "core/hle/service/nvnflinger/buffer_item.h"
10#include "core/hle/service/nvflinger/buffer_queue_consumer.h" 10#include "core/hle/service/nvnflinger/buffer_queue_consumer.h"
11#include "core/hle/service/nvflinger/buffer_queue_core.h" 11#include "core/hle/service/nvnflinger/buffer_queue_core.h"
12#include "core/hle/service/nvflinger/producer_listener.h" 12#include "core/hle/service/nvnflinger/producer_listener.h"
13#include "core/hle/service/nvflinger/ui/graphic_buffer.h" 13#include "core/hle/service/nvnflinger/ui/graphic_buffer.h"
14 14
15namespace Service::android { 15namespace Service::android {
16 16
@@ -31,7 +31,7 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
31 }))}; 31 }))};
32 32
33 if (num_acquired_buffers >= core->max_acquired_buffer_count + 1) { 33 if (num_acquired_buffers >= core->max_acquired_buffer_count + 1) {
34 LOG_ERROR(Service_NVFlinger, "max acquired buffer count reached: {} (max {})", 34 LOG_ERROR(Service_Nvnflinger, "max acquired buffer count reached: {} (max {})",
35 num_acquired_buffers, core->max_acquired_buffer_count); 35 num_acquired_buffers, core->max_acquired_buffer_count);
36 return Status::InvalidOperation; 36 return Status::InvalidOperation;
37 } 37 }
@@ -57,12 +57,12 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
57 if (desired_present < expected_present.count() - MAX_REASONABLE_NSEC || 57 if (desired_present < expected_present.count() - MAX_REASONABLE_NSEC ||
58 desired_present > expected_present.count()) { 58 desired_present > expected_present.count()) {
59 // This buffer is set to display in the near future, or desired_present is garbage. 59 // This buffer is set to display in the near future, or desired_present is garbage.
60 LOG_DEBUG(Service_NVFlinger, "nodrop desire={} expect={}", desired_present, 60 LOG_DEBUG(Service_Nvnflinger, "nodrop desire={} expect={}", desired_present,
61 expected_present.count()); 61 expected_present.count());
62 break; 62 break;
63 } 63 }
64 64
65 LOG_DEBUG(Service_NVFlinger, "drop desire={} expect={} size={}", desired_present, 65 LOG_DEBUG(Service_Nvnflinger, "drop desire={} expect={} size={}", desired_present,
66 expected_present.count(), core->queue.size()); 66 expected_present.count(), core->queue.size());
67 67
68 if (core->StillTracking(*front)) { 68 if (core->StillTracking(*front)) {
@@ -78,19 +78,19 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
78 const auto desired_present = front->timestamp; 78 const auto desired_present = front->timestamp;
79 if (desired_present > expected_present.count() && 79 if (desired_present > expected_present.count() &&
80 desired_present < expected_present.count() + MAX_REASONABLE_NSEC) { 80 desired_present < expected_present.count() + MAX_REASONABLE_NSEC) {
81 LOG_DEBUG(Service_NVFlinger, "defer desire={} expect={}", desired_present, 81 LOG_DEBUG(Service_Nvnflinger, "defer desire={} expect={}", desired_present,
82 expected_present.count()); 82 expected_present.count());
83 return Status::PresentLater; 83 return Status::PresentLater;
84 } 84 }
85 85
86 LOG_DEBUG(Service_NVFlinger, "accept desire={} expect={}", desired_present, 86 LOG_DEBUG(Service_Nvnflinger, "accept desire={} expect={}", desired_present,
87 expected_present.count()); 87 expected_present.count());
88 } 88 }
89 89
90 const auto slot = front->slot; 90 const auto slot = front->slot;
91 *out_buffer = *front; 91 *out_buffer = *front;
92 92
93 LOG_DEBUG(Service_NVFlinger, "acquiring slot={}", slot); 93 LOG_DEBUG(Service_Nvnflinger, "acquiring slot={}", slot);
94 94
95 // If the buffer has previously been acquired by the consumer, set graphic_buffer to nullptr to 95 // If the buffer has previously been acquired by the consumer, set graphic_buffer to nullptr to
96 // avoid unnecessarily remapping this buffer on the consumer side. 96 // avoid unnecessarily remapping this buffer on the consumer side.
@@ -109,7 +109,7 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
109 109
110Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence) { 110Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence) {
111 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 111 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
112 LOG_ERROR(Service_NVFlinger, "slot {} out of range", slot); 112 LOG_ERROR(Service_Nvnflinger, "slot {} out of range", slot);
113 return Status::BadValue; 113 return Status::BadValue;
114 } 114 }
115 115
@@ -127,7 +127,7 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc
127 auto current(core->queue.begin()); 127 auto current(core->queue.begin());
128 while (current != core->queue.end()) { 128 while (current != core->queue.end()) {
129 if (current->slot == slot) { 129 if (current->slot == slot) {
130 LOG_ERROR(Service_NVFlinger, "buffer slot {} pending release is currently queued", 130 LOG_ERROR(Service_Nvnflinger, "buffer slot {} pending release is currently queued",
131 slot); 131 slot);
132 return Status::BadValue; 132 return Status::BadValue;
133 } 133 }
@@ -140,7 +140,7 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc
140 140
141 listener = core->connected_producer_listener; 141 listener = core->connected_producer_listener;
142 142
143 LOG_DEBUG(Service_NVFlinger, "releasing slot {}", slot); 143 LOG_DEBUG(Service_Nvnflinger, "releasing slot {}", slot);
144 144
145 core->SignalDequeueCondition(); 145 core->SignalDequeueCondition();
146 } 146 }
@@ -156,16 +156,16 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc
156Status BufferQueueConsumer::Connect(std::shared_ptr<IConsumerListener> consumer_listener, 156Status BufferQueueConsumer::Connect(std::shared_ptr<IConsumerListener> consumer_listener,
157 bool controlled_by_app) { 157 bool controlled_by_app) {
158 if (consumer_listener == nullptr) { 158 if (consumer_listener == nullptr) {
159 LOG_ERROR(Service_NVFlinger, "consumer_listener may not be nullptr"); 159 LOG_ERROR(Service_Nvnflinger, "consumer_listener may not be nullptr");
160 return Status::BadValue; 160 return Status::BadValue;
161 } 161 }
162 162
163 LOG_DEBUG(Service_NVFlinger, "controlled_by_app={}", controlled_by_app); 163 LOG_DEBUG(Service_Nvnflinger, "controlled_by_app={}", controlled_by_app);
164 164
165 std::scoped_lock lock{core->mutex}; 165 std::scoped_lock lock{core->mutex};
166 166
167 if (core->is_abandoned) { 167 if (core->is_abandoned) {
168 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 168 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
169 return Status::NoInit; 169 return Status::NoInit;
170 } 170 }
171 171
@@ -177,14 +177,14 @@ Status BufferQueueConsumer::Connect(std::shared_ptr<IConsumerListener> consumer_
177 177
178Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) { 178Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) {
179 if (out_slot_mask == nullptr) { 179 if (out_slot_mask == nullptr) {
180 LOG_ERROR(Service_NVFlinger, "out_slot_mask may not be nullptr"); 180 LOG_ERROR(Service_Nvnflinger, "out_slot_mask may not be nullptr");
181 return Status::BadValue; 181 return Status::BadValue;
182 } 182 }
183 183
184 std::scoped_lock lock{core->mutex}; 184 std::scoped_lock lock{core->mutex};
185 185
186 if (core->is_abandoned) { 186 if (core->is_abandoned) {
187 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 187 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
188 return Status::NoInit; 188 return Status::NoInit;
189 } 189 }
190 190
@@ -205,7 +205,7 @@ Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) {
205 ++current; 205 ++current;
206 } 206 }
207 207
208 LOG_DEBUG(Service_NVFlinger, "returning mask {}", mask); 208 LOG_DEBUG(Service_Nvnflinger, "returning mask {}", mask);
209 *out_slot_mask = mask; 209 *out_slot_mask = mask;
210 return Status::NoError; 210 return Status::NoError;
211} 211}
diff --git a/src/core/hle/service/nvflinger/buffer_queue_consumer.h b/src/core/hle/service/nvnflinger/buffer_queue_consumer.h
index 4ec06ca13..50ed0bb5f 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_consumer.h
+++ b/src/core/hle/service/nvnflinger/buffer_queue_consumer.h
@@ -10,8 +10,8 @@
10#include <memory> 10#include <memory>
11 11
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "core/hle/service/nvflinger/buffer_queue_defs.h" 13#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
14#include "core/hle/service/nvflinger/status.h" 14#include "core/hle/service/nvnflinger/status.h"
15 15
16namespace Service::Nvidia::NvCore { 16namespace Service::Nvidia::NvCore {
17class NvMap; 17class NvMap;
diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.cpp b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp
index 3d1338e66..2dbe29616 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_core.cpp
+++ b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp
@@ -6,7 +6,7 @@
6 6
7#include "common/assert.h" 7#include "common/assert.h"
8 8
9#include "core/hle/service/nvflinger/buffer_queue_core.h" 9#include "core/hle/service/nvnflinger/buffer_queue_core.h"
10 10
11namespace Service::android { 11namespace Service::android {
12 12
@@ -82,7 +82,7 @@ s32 BufferQueueCore::GetPreallocatedBufferCountLocked() const {
82} 82}
83 83
84void BufferQueueCore::FreeBufferLocked(s32 slot) { 84void BufferQueueCore::FreeBufferLocked(s32 slot) {
85 LOG_DEBUG(Service_NVFlinger, "slot {}", slot); 85 LOG_DEBUG(Service_Nvnflinger, "slot {}", slot);
86 86
87 slots[slot].graphic_buffer.reset(); 87 slots[slot].graphic_buffer.reset();
88 88
diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.h b/src/core/hle/service/nvnflinger/buffer_queue_core.h
index 85b3bc4c1..9164f08a0 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_core.h
+++ b/src/core/hle/service/nvnflinger/buffer_queue_core.h
@@ -13,11 +13,11 @@
13#include <set> 13#include <set>
14#include <vector> 14#include <vector>
15 15
16#include "core/hle/service/nvflinger/buffer_item.h" 16#include "core/hle/service/nvnflinger/buffer_item.h"
17#include "core/hle/service/nvflinger/buffer_queue_defs.h" 17#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
18#include "core/hle/service/nvflinger/pixel_format.h" 18#include "core/hle/service/nvnflinger/pixel_format.h"
19#include "core/hle/service/nvflinger/status.h" 19#include "core/hle/service/nvnflinger/status.h"
20#include "core/hle/service/nvflinger/window.h" 20#include "core/hle/service/nvnflinger/window.h"
21 21
22namespace Service::android { 22namespace Service::android {
23 23
diff --git a/src/core/hle/service/nvflinger/buffer_queue_defs.h b/src/core/hle/service/nvnflinger/buffer_queue_defs.h
index 334445213..6fd3156f4 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_defs.h
+++ b/src/core/hle/service/nvnflinger/buffer_queue_defs.h
@@ -9,7 +9,7 @@
9#include <array> 9#include <array>
10 10
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/hle/service/nvflinger/buffer_slot.h" 12#include "core/hle/service/nvnflinger/buffer_slot.h"
13 13
14namespace Service::android::BufferQueueDefs { 14namespace Service::android::BufferQueueDefs {
15 15
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
index bcbe05b0d..cd0a13094 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
+++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
@@ -8,18 +8,18 @@
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "common/settings.h" 9#include "common/settings.h"
10#include "core/core.h" 10#include "core/core.h"
11#include "core/hle/kernel/hle_ipc.h"
12#include "core/hle/kernel/k_event.h" 11#include "core/hle/kernel/k_event.h"
13#include "core/hle/kernel/k_readable_event.h" 12#include "core/hle/kernel/k_readable_event.h"
14#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
14#include "core/hle/service/hle_ipc.h"
15#include "core/hle/service/kernel_helpers.h" 15#include "core/hle/service/kernel_helpers.h"
16#include "core/hle/service/nvdrv/core/nvmap.h" 16#include "core/hle/service/nvdrv/core/nvmap.h"
17#include "core/hle/service/nvflinger/buffer_queue_core.h" 17#include "core/hle/service/nvnflinger/buffer_queue_core.h"
18#include "core/hle/service/nvflinger/buffer_queue_producer.h" 18#include "core/hle/service/nvnflinger/buffer_queue_producer.h"
19#include "core/hle/service/nvflinger/consumer_listener.h" 19#include "core/hle/service/nvnflinger/consumer_listener.h"
20#include "core/hle/service/nvflinger/parcel.h" 20#include "core/hle/service/nvnflinger/parcel.h"
21#include "core/hle/service/nvflinger/ui/graphic_buffer.h" 21#include "core/hle/service/nvnflinger/ui/graphic_buffer.h"
22#include "core/hle/service/nvflinger/window.h" 22#include "core/hle/service/nvnflinger/window.h"
23#include "core/hle/service/vi/vi.h" 23#include "core/hle/service/vi/vi.h"
24 24
25namespace Service::android { 25namespace Service::android {
@@ -37,20 +37,20 @@ BufferQueueProducer::~BufferQueueProducer() {
37} 37}
38 38
39Status BufferQueueProducer::RequestBuffer(s32 slot, std::shared_ptr<GraphicBuffer>* buf) { 39Status BufferQueueProducer::RequestBuffer(s32 slot, std::shared_ptr<GraphicBuffer>* buf) {
40 LOG_DEBUG(Service_NVFlinger, "slot {}", slot); 40 LOG_DEBUG(Service_Nvnflinger, "slot {}", slot);
41 41
42 std::scoped_lock lock{core->mutex}; 42 std::scoped_lock lock{core->mutex};
43 43
44 if (core->is_abandoned) { 44 if (core->is_abandoned) {
45 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 45 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
46 return Status::NoInit; 46 return Status::NoInit;
47 } 47 }
48 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 48 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
49 LOG_ERROR(Service_NVFlinger, "slot index {} out of range [0, {})", slot, 49 LOG_ERROR(Service_Nvnflinger, "slot index {} out of range [0, {})", slot,
50 BufferQueueDefs::NUM_BUFFER_SLOTS); 50 BufferQueueDefs::NUM_BUFFER_SLOTS);
51 return Status::BadValue; 51 return Status::BadValue;
52 } else if (slots[slot].buffer_state != BufferState::Dequeued) { 52 } else if (slots[slot].buffer_state != BufferState::Dequeued) {
53 LOG_ERROR(Service_NVFlinger, "slot {} is not owned by the producer (state = {})", slot, 53 LOG_ERROR(Service_Nvnflinger, "slot {} is not owned by the producer (state = {})", slot,
54 slots[slot].buffer_state); 54 slots[slot].buffer_state);
55 return Status::BadValue; 55 return Status::BadValue;
56 } 56 }
@@ -62,7 +62,7 @@ Status BufferQueueProducer::RequestBuffer(s32 slot, std::shared_ptr<GraphicBuffe
62} 62}
63 63
64Status BufferQueueProducer::SetBufferCount(s32 buffer_count) { 64Status BufferQueueProducer::SetBufferCount(s32 buffer_count) {
65 LOG_DEBUG(Service_NVFlinger, "count = {}", buffer_count); 65 LOG_DEBUG(Service_Nvnflinger, "count = {}", buffer_count);
66 66
67 std::shared_ptr<IConsumerListener> listener; 67 std::shared_ptr<IConsumerListener> listener;
68 { 68 {
@@ -70,12 +70,12 @@ Status BufferQueueProducer::SetBufferCount(s32 buffer_count) {
70 core->WaitWhileAllocatingLocked(); 70 core->WaitWhileAllocatingLocked();
71 71
72 if (core->is_abandoned) { 72 if (core->is_abandoned) {
73 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 73 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
74 return Status::NoInit; 74 return Status::NoInit;
75 } 75 }
76 76
77 if (buffer_count > BufferQueueDefs::NUM_BUFFER_SLOTS) { 77 if (buffer_count > BufferQueueDefs::NUM_BUFFER_SLOTS) {
78 LOG_ERROR(Service_NVFlinger, "buffer_count {} too large (max {})", buffer_count, 78 LOG_ERROR(Service_Nvnflinger, "buffer_count {} too large (max {})", buffer_count,
79 BufferQueueDefs::NUM_BUFFER_SLOTS); 79 BufferQueueDefs::NUM_BUFFER_SLOTS);
80 return Status::BadValue; 80 return Status::BadValue;
81 } 81 }
@@ -83,7 +83,7 @@ Status BufferQueueProducer::SetBufferCount(s32 buffer_count) {
83 // There must be no dequeued buffers when changing the buffer count. 83 // There must be no dequeued buffers when changing the buffer count.
84 for (s32 s{}; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 84 for (s32 s{}; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
85 if (slots[s].buffer_state == BufferState::Dequeued) { 85 if (slots[s].buffer_state == BufferState::Dequeued) {
86 LOG_ERROR(Service_NVFlinger, "buffer owned by producer"); 86 LOG_ERROR(Service_Nvnflinger, "buffer owned by producer");
87 return Status::BadValue; 87 return Status::BadValue;
88 } 88 }
89 } 89 }
@@ -96,7 +96,7 @@ Status BufferQueueProducer::SetBufferCount(s32 buffer_count) {
96 96
97 const s32 min_buffer_slots = core->GetMinMaxBufferCountLocked(false); 97 const s32 min_buffer_slots = core->GetMinMaxBufferCountLocked(false);
98 if (buffer_count < min_buffer_slots) { 98 if (buffer_count < min_buffer_slots) {
99 LOG_ERROR(Service_NVFlinger, "requested buffer count {} is less than minimum {}", 99 LOG_ERROR(Service_Nvnflinger, "requested buffer count {} is less than minimum {}",
100 buffer_count, min_buffer_slots); 100 buffer_count, min_buffer_slots);
101 return Status::BadValue; 101 return Status::BadValue;
102 } 102 }
@@ -127,14 +127,14 @@ Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, St
127 127
128 while (try_again) { 128 while (try_again) {
129 if (core->is_abandoned) { 129 if (core->is_abandoned) {
130 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 130 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
131 return Status::NoInit; 131 return Status::NoInit;
132 } 132 }
133 133
134 const s32 max_buffer_count = core->GetMaxBufferCountLocked(async); 134 const s32 max_buffer_count = core->GetMaxBufferCountLocked(async);
135 if (async && core->override_max_buffer_count) { 135 if (async && core->override_max_buffer_count) {
136 if (core->override_max_buffer_count < max_buffer_count) { 136 if (core->override_max_buffer_count < max_buffer_count) {
137 LOG_ERROR(Service_NVFlinger, "async mode is invalid with buffer count override"); 137 LOG_ERROR(Service_Nvnflinger, "async mode is invalid with buffer count override");
138 return Status::BadValue; 138 return Status::BadValue;
139 } 139 }
140 } 140 }
@@ -176,7 +176,7 @@ Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, St
176 // Producers are not allowed to dequeue more than one buffer if they did not set a buffer 176 // Producers are not allowed to dequeue more than one buffer if they did not set a buffer
177 // count 177 // count
178 if (!core->override_max_buffer_count && dequeued_count) { 178 if (!core->override_max_buffer_count && dequeued_count) {
179 LOG_ERROR(Service_NVFlinger, 179 LOG_ERROR(Service_Nvnflinger,
180 "can't dequeue multiple buffers without setting the buffer count"); 180 "can't dequeue multiple buffers without setting the buffer count");
181 return Status::InvalidOperation; 181 return Status::InvalidOperation;
182 } 182 }
@@ -188,7 +188,7 @@ Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, St
188 const s32 new_undequeued_count = max_buffer_count - (dequeued_count + 1); 188 const s32 new_undequeued_count = max_buffer_count - (dequeued_count + 1);
189 const s32 min_undequeued_count = core->GetMinUndequeuedBufferCountLocked(async); 189 const s32 min_undequeued_count = core->GetMinUndequeuedBufferCountLocked(async);
190 if (new_undequeued_count < min_undequeued_count) { 190 if (new_undequeued_count < min_undequeued_count) {
191 LOG_ERROR(Service_NVFlinger, 191 LOG_ERROR(Service_Nvnflinger,
192 "min undequeued buffer count({}) exceeded (dequeued={} undequeued={})", 192 "min undequeued buffer count({}) exceeded (dequeued={} undequeued={})",
193 min_undequeued_count, dequeued_count, new_undequeued_count); 193 min_undequeued_count, dequeued_count, new_undequeued_count);
194 return Status::InvalidOperation; 194 return Status::InvalidOperation;
@@ -200,7 +200,7 @@ Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, St
200 // outrun the consumer. Wait here if it looks like we have too many buffers queued up. 200 // outrun the consumer. Wait here if it looks like we have too many buffers queued up.
201 const bool too_many_buffers = core->queue.size() > static_cast<size_t>(max_buffer_count); 201 const bool too_many_buffers = core->queue.size() > static_cast<size_t>(max_buffer_count);
202 if (too_many_buffers) { 202 if (too_many_buffers) {
203 LOG_ERROR(Service_NVFlinger, "queue size is {}, waiting", core->queue.size()); 203 LOG_ERROR(Service_Nvnflinger, "queue size is {}, waiting", core->queue.size());
204 } 204 }
205 205
206 // If no buffer is found, or if the queue has too many buffers outstanding, wait for a 206 // If no buffer is found, or if the queue has too many buffers outstanding, wait for a
@@ -226,11 +226,11 @@ Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, St
226 226
227Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool async, u32 width, 227Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool async, u32 width,
228 u32 height, PixelFormat format, u32 usage) { 228 u32 height, PixelFormat format, u32 usage) {
229 LOG_DEBUG(Service_NVFlinger, "async={} w={} h={} format={}, usage={}", async ? "true" : "false", 229 LOG_DEBUG(Service_Nvnflinger, "async={} w={} h={} format={}, usage={}",
230 width, height, format, usage); 230 async ? "true" : "false", width, height, format, usage);
231 231
232 if ((width != 0 && height == 0) || (width == 0 && height != 0)) { 232 if ((width != 0 && height == 0) || (width == 0 && height != 0)) {
233 LOG_ERROR(Service_NVFlinger, "invalid size: w={} h={}", width, height); 233 LOG_ERROR(Service_Nvnflinger, "invalid size: w={} h={}", width, height);
234 return Status::BadValue; 234 return Status::BadValue;
235 } 235 }
236 236
@@ -255,7 +255,7 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool
255 255
256 // This should not happen 256 // This should not happen
257 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 257 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
258 LOG_ERROR(Service_NVFlinger, "no available buffer slots"); 258 LOG_ERROR(Service_Nvnflinger, "no available buffer slots");
259 return Status::Busy; 259 return Status::Busy;
260 } 260 }
261 261
@@ -287,11 +287,11 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool
287 } 287 }
288 288
289 if ((return_flags & Status::BufferNeedsReallocation) != Status::None) { 289 if ((return_flags & Status::BufferNeedsReallocation) != Status::None) {
290 LOG_DEBUG(Service_NVFlinger, "allocating a new buffer for slot {}", *out_slot); 290 LOG_DEBUG(Service_Nvnflinger, "allocating a new buffer for slot {}", *out_slot);
291 291
292 auto graphic_buffer = std::make_shared<GraphicBuffer>(width, height, format, usage); 292 auto graphic_buffer = std::make_shared<GraphicBuffer>(width, height, format, usage);
293 if (graphic_buffer == nullptr) { 293 if (graphic_buffer == nullptr) {
294 LOG_ERROR(Service_NVFlinger, "creating GraphicBuffer failed"); 294 LOG_ERROR(Service_Nvnflinger, "creating GraphicBuffer failed");
295 return Status::NoMemory; 295 return Status::NoMemory;
296 } 296 }
297 297
@@ -299,7 +299,7 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool
299 std::scoped_lock lock{core->mutex}; 299 std::scoped_lock lock{core->mutex};
300 300
301 if (core->is_abandoned) { 301 if (core->is_abandoned) {
302 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 302 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
303 return Status::NoInit; 303 return Status::NoInit;
304 } 304 }
305 305
@@ -312,32 +312,32 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool
312 return_flags |= Status::BufferNeedsReallocation; 312 return_flags |= Status::BufferNeedsReallocation;
313 } 313 }
314 314
315 LOG_DEBUG(Service_NVFlinger, "returning slot={} frame={}, flags={}", *out_slot, 315 LOG_DEBUG(Service_Nvnflinger, "returning slot={} frame={}, flags={}", *out_slot,
316 slots[*out_slot].frame_number, return_flags); 316 slots[*out_slot].frame_number, return_flags);
317 317
318 return return_flags; 318 return return_flags;
319} 319}
320 320
321Status BufferQueueProducer::DetachBuffer(s32 slot) { 321Status BufferQueueProducer::DetachBuffer(s32 slot) {
322 LOG_DEBUG(Service_NVFlinger, "slot {}", slot); 322 LOG_DEBUG(Service_Nvnflinger, "slot {}", slot);
323 323
324 std::scoped_lock lock{core->mutex}; 324 std::scoped_lock lock{core->mutex};
325 325
326 if (core->is_abandoned) { 326 if (core->is_abandoned) {
327 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 327 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
328 return Status::NoInit; 328 return Status::NoInit;
329 } 329 }
330 330
331 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 331 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
332 LOG_ERROR(Service_NVFlinger, "slot {} out of range [0, {})", slot, 332 LOG_ERROR(Service_Nvnflinger, "slot {} out of range [0, {})", slot,
333 BufferQueueDefs::NUM_BUFFER_SLOTS); 333 BufferQueueDefs::NUM_BUFFER_SLOTS);
334 return Status::BadValue; 334 return Status::BadValue;
335 } else if (slots[slot].buffer_state != BufferState::Dequeued) { 335 } else if (slots[slot].buffer_state != BufferState::Dequeued) {
336 LOG_ERROR(Service_NVFlinger, "slot {} is not owned by the producer (state = {})", slot, 336 LOG_ERROR(Service_Nvnflinger, "slot {} is not owned by the producer (state = {})", slot,
337 slots[slot].buffer_state); 337 slots[slot].buffer_state);
338 return Status::BadValue; 338 return Status::BadValue;
339 } else if (!slots[slot].request_buffer_called) { 339 } else if (!slots[slot].request_buffer_called) {
340 LOG_ERROR(Service_NVFlinger, "buffer in slot {} has not been requested", slot); 340 LOG_ERROR(Service_Nvnflinger, "buffer in slot {} has not been requested", slot);
341 return Status::BadValue; 341 return Status::BadValue;
342 } 342 }
343 343
@@ -350,10 +350,10 @@ Status BufferQueueProducer::DetachBuffer(s32 slot) {
350Status BufferQueueProducer::DetachNextBuffer(std::shared_ptr<GraphicBuffer>* out_buffer, 350Status BufferQueueProducer::DetachNextBuffer(std::shared_ptr<GraphicBuffer>* out_buffer,
351 Fence* out_fence) { 351 Fence* out_fence) {
352 if (out_buffer == nullptr) { 352 if (out_buffer == nullptr) {
353 LOG_ERROR(Service_NVFlinger, "out_buffer must not be nullptr"); 353 LOG_ERROR(Service_Nvnflinger, "out_buffer must not be nullptr");
354 return Status::BadValue; 354 return Status::BadValue;
355 } else if (out_fence == nullptr) { 355 } else if (out_fence == nullptr) {
356 LOG_ERROR(Service_NVFlinger, "out_fence must not be nullptr"); 356 LOG_ERROR(Service_Nvnflinger, "out_fence must not be nullptr");
357 return Status::BadValue; 357 return Status::BadValue;
358 } 358 }
359 359
@@ -361,7 +361,7 @@ Status BufferQueueProducer::DetachNextBuffer(std::shared_ptr<GraphicBuffer>* out
361 core->WaitWhileAllocatingLocked(); 361 core->WaitWhileAllocatingLocked();
362 362
363 if (core->is_abandoned) { 363 if (core->is_abandoned) {
364 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 364 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
365 return Status::NoInit; 365 return Status::NoInit;
366 } 366 }
367 367
@@ -380,7 +380,7 @@ Status BufferQueueProducer::DetachNextBuffer(std::shared_ptr<GraphicBuffer>* out
380 return Status::NoMemory; 380 return Status::NoMemory;
381 } 381 }
382 382
383 LOG_DEBUG(Service_NVFlinger, "Detached slot {}", found); 383 LOG_DEBUG(Service_Nvnflinger, "Detached slot {}", found);
384 384
385 *out_buffer = slots[found].graphic_buffer; 385 *out_buffer = slots[found].graphic_buffer;
386 *out_fence = slots[found].fence; 386 *out_fence = slots[found].fence;
@@ -393,10 +393,10 @@ Status BufferQueueProducer::DetachNextBuffer(std::shared_ptr<GraphicBuffer>* out
393Status BufferQueueProducer::AttachBuffer(s32* out_slot, 393Status BufferQueueProducer::AttachBuffer(s32* out_slot,
394 const std::shared_ptr<GraphicBuffer>& buffer) { 394 const std::shared_ptr<GraphicBuffer>& buffer) {
395 if (out_slot == nullptr) { 395 if (out_slot == nullptr) {
396 LOG_ERROR(Service_NVFlinger, "out_slot must not be nullptr"); 396 LOG_ERROR(Service_Nvnflinger, "out_slot must not be nullptr");
397 return Status::BadValue; 397 return Status::BadValue;
398 } else if (buffer == nullptr) { 398 } else if (buffer == nullptr) {
399 LOG_ERROR(Service_NVFlinger, "Cannot attach nullptr buffer"); 399 LOG_ERROR(Service_Nvnflinger, "Cannot attach nullptr buffer");
400 return Status::BadValue; 400 return Status::BadValue;
401 } 401 }
402 402
@@ -413,13 +413,13 @@ Status BufferQueueProducer::AttachBuffer(s32* out_slot,
413 413
414 // This should not happen 414 // This should not happen
415 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 415 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
416 LOG_ERROR(Service_NVFlinger, "No available buffer slots"); 416 LOG_ERROR(Service_Nvnflinger, "No available buffer slots");
417 return Status::Busy; 417 return Status::Busy;
418 } 418 }
419 419
420 *out_slot = found; 420 *out_slot = found;
421 421
422 LOG_DEBUG(Service_NVFlinger, "Returning slot {} flags={}", *out_slot, return_flags); 422 LOG_DEBUG(Service_Nvnflinger, "Returning slot {} flags={}", *out_slot, return_flags);
423 423
424 slots[*out_slot].graphic_buffer = buffer; 424 slots[*out_slot].graphic_buffer = buffer;
425 slots[*out_slot].buffer_state = BufferState::Dequeued; 425 slots[*out_slot].buffer_state = BufferState::Dequeued;
@@ -451,7 +451,7 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
451 case NativeWindowScalingMode::NoScaleCrop: 451 case NativeWindowScalingMode::NoScaleCrop:
452 break; 452 break;
453 default: 453 default:
454 LOG_ERROR(Service_NVFlinger, "unknown scaling mode {}", scaling_mode); 454 LOG_ERROR(Service_Nvnflinger, "unknown scaling mode {}", scaling_mode);
455 return Status::BadValue; 455 return Status::BadValue;
456 } 456 }
457 457
@@ -464,38 +464,38 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
464 std::scoped_lock lock{core->mutex}; 464 std::scoped_lock lock{core->mutex};
465 465
466 if (core->is_abandoned) { 466 if (core->is_abandoned) {
467 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 467 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
468 return Status::NoInit; 468 return Status::NoInit;
469 } 469 }
470 470
471 const s32 max_buffer_count = core->GetMaxBufferCountLocked(async); 471 const s32 max_buffer_count = core->GetMaxBufferCountLocked(async);
472 if (async && core->override_max_buffer_count) { 472 if (async && core->override_max_buffer_count) {
473 if (core->override_max_buffer_count < max_buffer_count) { 473 if (core->override_max_buffer_count < max_buffer_count) {
474 LOG_ERROR(Service_NVFlinger, "async mode is invalid with " 474 LOG_ERROR(Service_Nvnflinger, "async mode is invalid with "
475 "buffer count override"); 475 "buffer count override");
476 return Status::BadValue; 476 return Status::BadValue;
477 } 477 }
478 } 478 }
479 479
480 if (slot < 0 || slot >= max_buffer_count) { 480 if (slot < 0 || slot >= max_buffer_count) {
481 LOG_ERROR(Service_NVFlinger, "slot index {} out of range [0, {})", slot, 481 LOG_ERROR(Service_Nvnflinger, "slot index {} out of range [0, {})", slot,
482 max_buffer_count); 482 max_buffer_count);
483 return Status::BadValue; 483 return Status::BadValue;
484 } else if (slots[slot].buffer_state != BufferState::Dequeued) { 484 } else if (slots[slot].buffer_state != BufferState::Dequeued) {
485 LOG_ERROR(Service_NVFlinger, 485 LOG_ERROR(Service_Nvnflinger,
486 "slot {} is not owned by the producer " 486 "slot {} is not owned by the producer "
487 "(state = {})", 487 "(state = {})",
488 slot, slots[slot].buffer_state); 488 slot, slots[slot].buffer_state);
489 return Status::BadValue; 489 return Status::BadValue;
490 } else if (!slots[slot].request_buffer_called) { 490 } else if (!slots[slot].request_buffer_called) {
491 LOG_ERROR(Service_NVFlinger, 491 LOG_ERROR(Service_Nvnflinger,
492 "slot {} was queued without requesting " 492 "slot {} was queued without requesting "
493 "a buffer", 493 "a buffer",
494 slot); 494 slot);
495 return Status::BadValue; 495 return Status::BadValue;
496 } 496 }
497 497
498 LOG_DEBUG(Service_NVFlinger, 498 LOG_DEBUG(Service_Nvnflinger,
499 "slot={} frame={} time={} crop=[{},{},{},{}] transform={} scale={}", slot, 499 "slot={} frame={} time={} crop=[{},{},{},{}] transform={} scale={}", slot,
500 core->frame_counter + 1, timestamp, crop.Left(), crop.Top(), crop.Right(), 500 core->frame_counter + 1, timestamp, crop.Left(), crop.Top(), crop.Right(),
501 crop.Bottom(), transform, scaling_mode); 501 crop.Bottom(), transform, scaling_mode);
@@ -506,7 +506,7 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
506 [[maybe_unused]] const bool unused = crop.Intersect(buffer_rect, &cropped_rect); 506 [[maybe_unused]] const bool unused = crop.Intersect(buffer_rect, &cropped_rect);
507 507
508 if (cropped_rect != crop) { 508 if (cropped_rect != crop) {
509 LOG_ERROR(Service_NVFlinger, "crop rect is not contained within the buffer in slot {}", 509 LOG_ERROR(Service_Nvnflinger, "crop rect is not contained within the buffer in slot {}",
510 slot); 510 slot);
511 return Status::BadValue; 511 return Status::BadValue;
512 } 512 }
@@ -598,21 +598,21 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
598} 598}
599 599
600void BufferQueueProducer::CancelBuffer(s32 slot, const Fence& fence) { 600void BufferQueueProducer::CancelBuffer(s32 slot, const Fence& fence) {
601 LOG_DEBUG(Service_NVFlinger, "slot {}", slot); 601 LOG_DEBUG(Service_Nvnflinger, "slot {}", slot);
602 602
603 std::scoped_lock lock{core->mutex}; 603 std::scoped_lock lock{core->mutex};
604 604
605 if (core->is_abandoned) { 605 if (core->is_abandoned) {
606 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 606 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
607 return; 607 return;
608 } 608 }
609 609
610 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 610 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
611 LOG_ERROR(Service_NVFlinger, "slot index {} out of range [0, {})", slot, 611 LOG_ERROR(Service_Nvnflinger, "slot index {} out of range [0, {})", slot,
612 BufferQueueDefs::NUM_BUFFER_SLOTS); 612 BufferQueueDefs::NUM_BUFFER_SLOTS);
613 return; 613 return;
614 } else if (slots[slot].buffer_state != BufferState::Dequeued) { 614 } else if (slots[slot].buffer_state != BufferState::Dequeued) {
615 LOG_ERROR(Service_NVFlinger, "slot {} is not owned by the producer (state = {})", slot, 615 LOG_ERROR(Service_Nvnflinger, "slot {} is not owned by the producer (state = {})", slot,
616 slots[slot].buffer_state); 616 slots[slot].buffer_state);
617 return; 617 return;
618 } 618 }
@@ -629,12 +629,12 @@ Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) {
629 std::scoped_lock lock{core->mutex}; 629 std::scoped_lock lock{core->mutex};
630 630
631 if (out_value == nullptr) { 631 if (out_value == nullptr) {
632 LOG_ERROR(Service_NVFlinger, "outValue was nullptr"); 632 LOG_ERROR(Service_Nvnflinger, "outValue was nullptr");
633 return Status::BadValue; 633 return Status::BadValue;
634 } 634 }
635 635
636 if (core->is_abandoned) { 636 if (core->is_abandoned) {
637 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 637 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
638 return Status::NoInit; 638 return Status::NoInit;
639 } 639 }
640 640
@@ -666,7 +666,7 @@ Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) {
666 return Status::BadValue; 666 return Status::BadValue;
667 } 667 }
668 668
669 LOG_DEBUG(Service_NVFlinger, "what = {}, value = {}", what, value); 669 LOG_DEBUG(Service_Nvnflinger, "what = {}, value = {}", what, value);
670 670
671 *out_value = static_cast<s32>(value); 671 *out_value = static_cast<s32>(value);
672 672
@@ -678,26 +678,26 @@ Status BufferQueueProducer::Connect(const std::shared_ptr<IProducerListener>& li
678 QueueBufferOutput* output) { 678 QueueBufferOutput* output) {
679 std::scoped_lock lock{core->mutex}; 679 std::scoped_lock lock{core->mutex};
680 680
681 LOG_DEBUG(Service_NVFlinger, "api = {} producer_controlled_by_app = {}", api, 681 LOG_DEBUG(Service_Nvnflinger, "api = {} producer_controlled_by_app = {}", api,
682 producer_controlled_by_app); 682 producer_controlled_by_app);
683 683
684 if (core->is_abandoned) { 684 if (core->is_abandoned) {
685 LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); 685 LOG_ERROR(Service_Nvnflinger, "BufferQueue has been abandoned");
686 return Status::NoInit; 686 return Status::NoInit;
687 } 687 }
688 688
689 if (core->consumer_listener == nullptr) { 689 if (core->consumer_listener == nullptr) {
690 LOG_ERROR(Service_NVFlinger, "BufferQueue has no consumer"); 690 LOG_ERROR(Service_Nvnflinger, "BufferQueue has no consumer");
691 return Status::NoInit; 691 return Status::NoInit;
692 } 692 }
693 693
694 if (output == nullptr) { 694 if (output == nullptr) {
695 LOG_ERROR(Service_NVFlinger, "output was nullptr"); 695 LOG_ERROR(Service_Nvnflinger, "output was nullptr");
696 return Status::BadValue; 696 return Status::BadValue;
697 } 697 }
698 698
699 if (core->connected_api != NativeWindowApi::NoConnectedApi) { 699 if (core->connected_api != NativeWindowApi::NoConnectedApi) {
700 LOG_ERROR(Service_NVFlinger, "already connected (cur = {} req = {})", core->connected_api, 700 LOG_ERROR(Service_Nvnflinger, "already connected (cur = {} req = {})", core->connected_api,
701 api); 701 api);
702 return Status::BadValue; 702 return Status::BadValue;
703 } 703 }
@@ -714,7 +714,7 @@ Status BufferQueueProducer::Connect(const std::shared_ptr<IProducerListener>& li
714 core->connected_producer_listener = listener; 714 core->connected_producer_listener = listener;
715 break; 715 break;
716 default: 716 default:
717 LOG_ERROR(Service_NVFlinger, "unknown api = {}", api); 717 LOG_ERROR(Service_Nvnflinger, "unknown api = {}", api);
718 status = Status::BadValue; 718 status = Status::BadValue;
719 break; 719 break;
720 } 720 }
@@ -727,7 +727,7 @@ Status BufferQueueProducer::Connect(const std::shared_ptr<IProducerListener>& li
727} 727}
728 728
729Status BufferQueueProducer::Disconnect(NativeWindowApi api) { 729Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
730 LOG_DEBUG(Service_NVFlinger, "api = {}", api); 730 LOG_DEBUG(Service_Nvnflinger, "api = {}", api);
731 731
732 Status status = Status::NoError; 732 Status status = Status::NoError;
733 std::shared_ptr<IConsumerListener> listener; 733 std::shared_ptr<IConsumerListener> listener;
@@ -762,13 +762,13 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
762 buffer_wait_event->Signal(); 762 buffer_wait_event->Signal();
763 listener = core->consumer_listener; 763 listener = core->consumer_listener;
764 } else { 764 } else {
765 LOG_ERROR(Service_NVFlinger, "still connected to another api (cur = {} req = {})", 765 LOG_ERROR(Service_Nvnflinger, "still connected to another api (cur = {} req = {})",
766 core->connected_api, api); 766 core->connected_api, api);
767 status = Status::BadValue; 767 status = Status::BadValue;
768 } 768 }
769 break; 769 break;
770 default: 770 default:
771 LOG_ERROR(Service_NVFlinger, "unknown api = {}", api); 771 LOG_ERROR(Service_Nvnflinger, "unknown api = {}", api);
772 status = Status::BadValue; 772 status = Status::BadValue;
773 break; 773 break;
774 } 774 }
@@ -784,7 +784,7 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
784 784
785Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot, 785Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
786 const std::shared_ptr<GraphicBuffer>& buffer) { 786 const std::shared_ptr<GraphicBuffer>& buffer) {
787 LOG_DEBUG(Service_NVFlinger, "slot {}", slot); 787 LOG_DEBUG(Service_Nvnflinger, "slot {}", slot);
788 788
789 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 789 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
790 return Status::BadValue; 790 return Status::BadValue;
@@ -813,7 +813,7 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
813 return Status::NoError; 813 return Status::NoError;
814} 814}
815 815
816void BufferQueueProducer::Transact(Kernel::HLERequestContext& ctx, TransactionId code, u32 flags) { 816void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u32 flags) {
817 Status status{Status::NoError}; 817 Status status{Status::NoError};
818 InputParcel parcel_in{ctx.ReadBuffer()}; 818 InputParcel parcel_in{ctx.ReadBuffer()};
819 OutputParcel parcel_out{}; 819 OutputParcel parcel_out{};
@@ -914,7 +914,7 @@ void BufferQueueProducer::Transact(Kernel::HLERequestContext& ctx, TransactionId
914 break; 914 break;
915 } 915 }
916 case TransactionId::GetBufferHistory: 916 case TransactionId::GetBufferHistory:
917 LOG_WARNING(Service_NVFlinger, "(STUBBED) called, transaction=GetBufferHistory"); 917 LOG_WARNING(Service_Nvnflinger, "(STUBBED) called, transaction=GetBufferHistory");
918 break; 918 break;
919 default: 919 default:
920 ASSERT_MSG(false, "Unimplemented TransactionId {}", code); 920 ASSERT_MSG(false, "Unimplemented TransactionId {}", code);
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.h b/src/core/hle/service/nvnflinger/buffer_queue_producer.h
index 1d380480f..d4201c104 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.h
+++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.h
@@ -12,13 +12,13 @@
12 12
13#include "common/common_funcs.h" 13#include "common/common_funcs.h"
14#include "core/hle/service/nvdrv/nvdata.h" 14#include "core/hle/service/nvdrv/nvdata.h"
15#include "core/hle/service/nvflinger/binder.h" 15#include "core/hle/service/nvnflinger/binder.h"
16#include "core/hle/service/nvflinger/buffer_queue_defs.h" 16#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
17#include "core/hle/service/nvflinger/buffer_slot.h" 17#include "core/hle/service/nvnflinger/buffer_slot.h"
18#include "core/hle/service/nvflinger/graphic_buffer_producer.h" 18#include "core/hle/service/nvnflinger/graphic_buffer_producer.h"
19#include "core/hle/service/nvflinger/pixel_format.h" 19#include "core/hle/service/nvnflinger/pixel_format.h"
20#include "core/hle/service/nvflinger/status.h" 20#include "core/hle/service/nvnflinger/status.h"
21#include "core/hle/service/nvflinger/window.h" 21#include "core/hle/service/nvnflinger/window.h"
22 22
23namespace Kernel { 23namespace Kernel {
24class KernelCore; 24class KernelCore;
@@ -46,7 +46,7 @@ public:
46 Service::Nvidia::NvCore::NvMap& nvmap_); 46 Service::Nvidia::NvCore::NvMap& nvmap_);
47 ~BufferQueueProducer(); 47 ~BufferQueueProducer();
48 48
49 void Transact(Kernel::HLERequestContext& ctx, android::TransactionId code, u32 flags) override; 49 void Transact(HLERequestContext& ctx, android::TransactionId code, u32 flags) override;
50 50
51 Kernel::KReadableEvent& GetNativeHandle() override; 51 Kernel::KReadableEvent& GetNativeHandle() override;
52 52
diff --git a/src/core/hle/service/nvflinger/buffer_slot.h b/src/core/hle/service/nvnflinger/buffer_slot.h
index 0cd0e9964..d25bca049 100644
--- a/src/core/hle/service/nvflinger/buffer_slot.h
+++ b/src/core/hle/service/nvnflinger/buffer_slot.h
@@ -9,7 +9,7 @@
9#include <memory> 9#include <memory>
10 10
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/hle/service/nvflinger/ui/fence.h" 12#include "core/hle/service/nvnflinger/ui/fence.h"
13 13
14namespace Service::android { 14namespace Service::android {
15 15
diff --git a/src/core/hle/service/nvflinger/buffer_transform_flags.h b/src/core/hle/service/nvnflinger/buffer_transform_flags.h
index 67aa5dad6..67aa5dad6 100644
--- a/src/core/hle/service/nvflinger/buffer_transform_flags.h
+++ b/src/core/hle/service/nvnflinger/buffer_transform_flags.h
diff --git a/src/core/hle/service/nvflinger/consumer_base.cpp b/src/core/hle/service/nvnflinger/consumer_base.cpp
index 982531e2d..4dcda8dac 100644
--- a/src/core/hle/service/nvflinger/consumer_base.cpp
+++ b/src/core/hle/service/nvnflinger/consumer_base.cpp
@@ -6,11 +6,11 @@
6 6
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "core/hle/service/nvflinger/buffer_item.h" 9#include "core/hle/service/nvnflinger/buffer_item.h"
10#include "core/hle/service/nvflinger/buffer_queue_consumer.h" 10#include "core/hle/service/nvnflinger/buffer_queue_consumer.h"
11#include "core/hle/service/nvflinger/buffer_queue_core.h" 11#include "core/hle/service/nvnflinger/buffer_queue_core.h"
12#include "core/hle/service/nvflinger/consumer_base.h" 12#include "core/hle/service/nvnflinger/consumer_base.h"
13#include "core/hle/service/nvflinger/ui/graphic_buffer.h" 13#include "core/hle/service/nvnflinger/ui/graphic_buffer.h"
14 14
15namespace Service::android { 15namespace Service::android {
16 16
@@ -28,7 +28,7 @@ void ConsumerBase::Connect(bool controlled_by_app) {
28} 28}
29 29
30void ConsumerBase::FreeBufferLocked(s32 slot_index) { 30void ConsumerBase::FreeBufferLocked(s32 slot_index) {
31 LOG_DEBUG(Service_NVFlinger, "slot_index={}", slot_index); 31 LOG_DEBUG(Service_Nvnflinger, "slot_index={}", slot_index);
32 32
33 slots[slot_index].graphic_buffer = nullptr; 33 slots[slot_index].graphic_buffer = nullptr;
34 slots[slot_index].fence = Fence::NoFence(); 34 slots[slot_index].fence = Fence::NoFence();
@@ -36,17 +36,17 @@ void ConsumerBase::FreeBufferLocked(s32 slot_index) {
36} 36}
37 37
38void ConsumerBase::OnFrameAvailable(const BufferItem& item) { 38void ConsumerBase::OnFrameAvailable(const BufferItem& item) {
39 LOG_DEBUG(Service_NVFlinger, "called"); 39 LOG_DEBUG(Service_Nvnflinger, "called");
40} 40}
41 41
42void ConsumerBase::OnFrameReplaced(const BufferItem& item) { 42void ConsumerBase::OnFrameReplaced(const BufferItem& item) {
43 LOG_DEBUG(Service_NVFlinger, "called"); 43 LOG_DEBUG(Service_Nvnflinger, "called");
44} 44}
45 45
46void ConsumerBase::OnBuffersReleased() { 46void ConsumerBase::OnBuffersReleased() {
47 std::scoped_lock lock{mutex}; 47 std::scoped_lock lock{mutex};
48 48
49 LOG_DEBUG(Service_NVFlinger, "called"); 49 LOG_DEBUG(Service_Nvnflinger, "called");
50 50
51 if (is_abandoned) { 51 if (is_abandoned) {
52 // Nothing to do if we're already abandoned. 52 // Nothing to do if we're already abandoned.
@@ -77,7 +77,7 @@ Status ConsumerBase::AcquireBufferLocked(BufferItem* item, std::chrono::nanoseco
77 slots[item->slot].frame_number = item->frame_number; 77 slots[item->slot].frame_number = item->frame_number;
78 slots[item->slot].fence = item->fence; 78 slots[item->slot].fence = item->fence;
79 79
80 LOG_DEBUG(Service_NVFlinger, "slot={}", item->slot); 80 LOG_DEBUG(Service_Nvnflinger, "slot={}", item->slot);
81 81
82 return Status::NoError; 82 return Status::NoError;
83} 83}
@@ -85,7 +85,7 @@ Status ConsumerBase::AcquireBufferLocked(BufferItem* item, std::chrono::nanoseco
85Status ConsumerBase::AddReleaseFenceLocked(s32 slot, 85Status ConsumerBase::AddReleaseFenceLocked(s32 slot,
86 const std::shared_ptr<GraphicBuffer>& graphic_buffer, 86 const std::shared_ptr<GraphicBuffer>& graphic_buffer,
87 const Fence& fence) { 87 const Fence& fence) {
88 LOG_DEBUG(Service_NVFlinger, "slot={}", slot); 88 LOG_DEBUG(Service_Nvnflinger, "slot={}", slot);
89 89
90 // If consumer no longer tracks this graphic_buffer, we can safely 90 // If consumer no longer tracks this graphic_buffer, we can safely
91 // drop this fence, as it will never be received by the producer. 91 // drop this fence, as it will never be received by the producer.
@@ -109,7 +109,7 @@ Status ConsumerBase::ReleaseBufferLocked(s32 slot,
109 return Status::NoError; 109 return Status::NoError;
110 } 110 }
111 111
112 LOG_DEBUG(Service_NVFlinger, "slot={}", slot); 112 LOG_DEBUG(Service_Nvnflinger, "slot={}", slot);
113 Status err = consumer->ReleaseBuffer(slot, slots[slot].frame_number, slots[slot].fence); 113 Status err = consumer->ReleaseBuffer(slot, slots[slot].frame_number, slots[slot].fence);
114 if (err == Status::StaleBufferSlot) { 114 if (err == Status::StaleBufferSlot) {
115 FreeBufferLocked(slot); 115 FreeBufferLocked(slot);
diff --git a/src/core/hle/service/nvflinger/consumer_base.h b/src/core/hle/service/nvnflinger/consumer_base.h
index 9a8a5f6bb..264829414 100644
--- a/src/core/hle/service/nvflinger/consumer_base.h
+++ b/src/core/hle/service/nvnflinger/consumer_base.h
@@ -12,9 +12,9 @@
12#include <mutex> 12#include <mutex>
13 13
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "core/hle/service/nvflinger/buffer_queue_defs.h" 15#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
16#include "core/hle/service/nvflinger/consumer_listener.h" 16#include "core/hle/service/nvnflinger/consumer_listener.h"
17#include "core/hle/service/nvflinger/status.h" 17#include "core/hle/service/nvnflinger/status.h"
18 18
19namespace Service::android { 19namespace Service::android {
20 20
diff --git a/src/core/hle/service/nvflinger/consumer_listener.h b/src/core/hle/service/nvnflinger/consumer_listener.h
index 74a193988..74a193988 100644
--- a/src/core/hle/service/nvflinger/consumer_listener.h
+++ b/src/core/hle/service/nvnflinger/consumer_listener.h
diff --git a/src/core/hle/service/nvflinger/graphic_buffer_producer.cpp b/src/core/hle/service/nvnflinger/graphic_buffer_producer.cpp
index 769e8c0a3..d72b49a8e 100644
--- a/src/core/hle/service/nvflinger/graphic_buffer_producer.cpp
+++ b/src/core/hle/service/nvnflinger/graphic_buffer_producer.cpp
@@ -4,8 +4,8 @@
4// Parts of this implementation were based on: 4// Parts of this implementation were based on:
5// https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/IGraphicBufferProducer.cpp 5// https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/IGraphicBufferProducer.cpp
6 6
7#include "core/hle/service/nvflinger/graphic_buffer_producer.h" 7#include "core/hle/service/nvnflinger/graphic_buffer_producer.h"
8#include "core/hle/service/nvflinger/parcel.h" 8#include "core/hle/service/nvnflinger/parcel.h"
9 9
10namespace Service::android { 10namespace Service::android {
11 11
diff --git a/src/core/hle/service/nvflinger/graphic_buffer_producer.h b/src/core/hle/service/nvnflinger/graphic_buffer_producer.h
index 2969f0fd5..21d7b31f3 100644
--- a/src/core/hle/service/nvflinger/graphic_buffer_producer.h
+++ b/src/core/hle/service/nvnflinger/graphic_buffer_producer.h
@@ -9,8 +9,8 @@
9#include "common/common_funcs.h" 9#include "common/common_funcs.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/math_util.h" 11#include "common/math_util.h"
12#include "core/hle/service/nvflinger/ui/fence.h" 12#include "core/hle/service/nvnflinger/ui/fence.h"
13#include "core/hle/service/nvflinger/window.h" 13#include "core/hle/service/nvnflinger/window.h"
14 14
15namespace Service::android { 15namespace Service::android {
16 16
diff --git a/src/core/hle/service/nvflinger/hos_binder_driver_server.cpp b/src/core/hle/service/nvnflinger/hos_binder_driver_server.cpp
index dc9b2a9ec..b86a79ec9 100644
--- a/src/core/hle/service/nvflinger/hos_binder_driver_server.cpp
+++ b/src/core/hle/service/nvnflinger/hos_binder_driver_server.cpp
@@ -4,9 +4,9 @@
4#include <mutex> 4#include <mutex>
5 5
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "core/hle/service/nvflinger/hos_binder_driver_server.h" 7#include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
8 8
9namespace Service::NVFlinger { 9namespace Service::Nvnflinger {
10 10
11HosBinderDriverServer::HosBinderDriverServer(Core::System& system_) 11HosBinderDriverServer::HosBinderDriverServer(Core::System& system_)
12 : service_context(system_, "HosBinderDriverServer") {} 12 : service_context(system_, "HosBinderDriverServer") {}
@@ -33,4 +33,4 @@ android::IBinder* HosBinderDriverServer::TryGetProducer(u64 id) {
33 return {}; 33 return {};
34} 34}
35 35
36} // namespace Service::NVFlinger 36} // namespace Service::Nvnflinger
diff --git a/src/core/hle/service/nvflinger/hos_binder_driver_server.h b/src/core/hle/service/nvnflinger/hos_binder_driver_server.h
index 8fddc1206..58bb9469a 100644
--- a/src/core/hle/service/nvflinger/hos_binder_driver_server.h
+++ b/src/core/hle/service/nvnflinger/hos_binder_driver_server.h
@@ -9,13 +9,13 @@
9 9
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "core/hle/service/kernel_helpers.h" 11#include "core/hle/service/kernel_helpers.h"
12#include "core/hle/service/nvflinger/binder.h" 12#include "core/hle/service/nvnflinger/binder.h"
13 13
14namespace Core { 14namespace Core {
15class System; 15class System;
16} 16}
17 17
18namespace Service::NVFlinger { 18namespace Service::Nvnflinger {
19 19
20class HosBinderDriverServer final { 20class HosBinderDriverServer final {
21public: 21public:
@@ -34,4 +34,4 @@ private:
34 u64 last_id{}; 34 u64 last_id{};
35}; 35};
36 36
37} // namespace Service::NVFlinger 37} // namespace Service::Nvnflinger
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp
index f4416f5b2..4988e6e17 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp
@@ -15,11 +15,11 @@
15#include "core/hle/kernel/k_readable_event.h" 15#include "core/hle/kernel/k_readable_event.h"
16#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" 16#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
17#include "core/hle/service/nvdrv/nvdrv.h" 17#include "core/hle/service/nvdrv/nvdrv.h"
18#include "core/hle/service/nvflinger/buffer_item_consumer.h" 18#include "core/hle/service/nvnflinger/buffer_item_consumer.h"
19#include "core/hle/service/nvflinger/buffer_queue_core.h" 19#include "core/hle/service/nvnflinger/buffer_queue_core.h"
20#include "core/hle/service/nvflinger/hos_binder_driver_server.h" 20#include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
21#include "core/hle/service/nvflinger/nvflinger.h" 21#include "core/hle/service/nvnflinger/nvnflinger.h"
22#include "core/hle/service/nvflinger/ui/graphic_buffer.h" 22#include "core/hle/service/nvnflinger/ui/graphic_buffer.h"
23#include "core/hle/service/vi/display/vi_display.h" 23#include "core/hle/service/vi/display/vi_display.h"
24#include "core/hle/service/vi/layer/vi_layer.h" 24#include "core/hle/service/vi/layer/vi_layer.h"
25#include "core/hle/service/vi/vi_results.h" 25#include "core/hle/service/vi/vi_results.h"
@@ -27,11 +27,11 @@
27#include "video_core/host1x/host1x.h" 27#include "video_core/host1x/host1x.h"
28#include "video_core/host1x/syncpoint_manager.h" 28#include "video_core/host1x/syncpoint_manager.h"
29 29
30namespace Service::NVFlinger { 30namespace Service::Nvnflinger {
31 31
32constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60}; 32constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60};
33 33
34void NVFlinger::SplitVSync(std::stop_token stop_token) { 34void Nvnflinger::SplitVSync(std::stop_token stop_token) {
35 system.RegisterHostThread(); 35 system.RegisterHostThread();
36 std::string name = "VSyncThread"; 36 std::string name = "VSyncThread";
37 MicroProfileOnThreadCreate(name.c_str()); 37 MicroProfileOnThreadCreate(name.c_str());
@@ -54,8 +54,8 @@ void NVFlinger::SplitVSync(std::stop_token stop_token) {
54 } 54 }
55} 55}
56 56
57NVFlinger::NVFlinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_) 57Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_)
58 : system(system_), service_context(system_, "nvflinger"), 58 : system(system_), service_context(system_, "nvnflinger"),
59 hos_binder_driver_server(hos_binder_driver_server_) { 59 hos_binder_driver_server(hos_binder_driver_server_) {
60 displays.emplace_back(0, "Default", hos_binder_driver_server, service_context, system); 60 displays.emplace_back(0, "Default", hos_binder_driver_server, service_context, system);
61 displays.emplace_back(1, "External", hos_binder_driver_server, service_context, system); 61 displays.emplace_back(1, "External", hos_binder_driver_server, service_context, system);
@@ -92,7 +92,7 @@ NVFlinger::NVFlinger(Core::System& system_, HosBinderDriverServer& hos_binder_dr
92 } 92 }
93} 93}
94 94
95NVFlinger::~NVFlinger() { 95Nvnflinger::~Nvnflinger() {
96 if (system.IsMulticore()) { 96 if (system.IsMulticore()) {
97 system.CoreTiming().UnscheduleEvent(multi_composition_event, {}); 97 system.CoreTiming().UnscheduleEvent(multi_composition_event, {});
98 vsync_thread.request_stop(); 98 vsync_thread.request_stop();
@@ -109,7 +109,7 @@ NVFlinger::~NVFlinger() {
109 } 109 }
110} 110}
111 111
112void NVFlinger::ShutdownLayers() { 112void Nvnflinger::ShutdownLayers() {
113 for (auto& display : displays) { 113 for (auto& display : displays) {
114 for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) { 114 for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) {
115 display.GetLayer(layer).Core().NotifyShutdown(); 115 display.GetLayer(layer).Core().NotifyShutdown();
@@ -117,15 +117,15 @@ void NVFlinger::ShutdownLayers() {
117 } 117 }
118} 118}
119 119
120void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { 120void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
121 nvdrv = std::move(instance); 121 nvdrv = std::move(instance);
122 disp_fd = nvdrv->Open("/dev/nvdisp_disp0"); 122 disp_fd = nvdrv->Open("/dev/nvdisp_disp0");
123} 123}
124 124
125std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) { 125std::optional<u64> Nvnflinger::OpenDisplay(std::string_view name) {
126 const auto lock_guard = Lock(); 126 const auto lock_guard = Lock();
127 127
128 LOG_DEBUG(Service_NVFlinger, "Opening \"{}\" display", name); 128 LOG_DEBUG(Service_Nvnflinger, "Opening \"{}\" display", name);
129 129
130 const auto itr = 130 const auto itr =
131 std::find_if(displays.begin(), displays.end(), 131 std::find_if(displays.begin(), displays.end(),
@@ -138,7 +138,7 @@ std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) {
138 return itr->GetID(); 138 return itr->GetID();
139} 139}
140 140
141bool NVFlinger::CloseDisplay(u64 display_id) { 141bool Nvnflinger::CloseDisplay(u64 display_id) {
142 const auto lock_guard = Lock(); 142 const auto lock_guard = Lock();
143 auto* const display = FindDisplay(display_id); 143 auto* const display = FindDisplay(display_id);
144 144
@@ -151,7 +151,7 @@ bool NVFlinger::CloseDisplay(u64 display_id) {
151 return true; 151 return true;
152} 152}
153 153
154std::optional<u64> NVFlinger::CreateLayer(u64 display_id) { 154std::optional<u64> Nvnflinger::CreateLayer(u64 display_id) {
155 const auto lock_guard = Lock(); 155 const auto lock_guard = Lock();
156 auto* const display = FindDisplay(display_id); 156 auto* const display = FindDisplay(display_id);
157 157
@@ -164,12 +164,12 @@ std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
164 return layer_id; 164 return layer_id;
165} 165}
166 166
167void NVFlinger::CreateLayerAtId(VI::Display& display, u64 layer_id) { 167void Nvnflinger::CreateLayerAtId(VI::Display& display, u64 layer_id) {
168 const auto buffer_id = next_buffer_queue_id++; 168 const auto buffer_id = next_buffer_queue_id++;
169 display.CreateLayer(layer_id, buffer_id, nvdrv->container); 169 display.CreateLayer(layer_id, buffer_id, nvdrv->container);
170} 170}
171 171
172void NVFlinger::CloseLayer(u64 layer_id) { 172void Nvnflinger::CloseLayer(u64 layer_id) {
173 const auto lock_guard = Lock(); 173 const auto lock_guard = Lock();
174 174
175 for (auto& display : displays) { 175 for (auto& display : displays) {
@@ -177,7 +177,7 @@ void NVFlinger::CloseLayer(u64 layer_id) {
177 } 177 }
178} 178}
179 179
180std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) { 180std::optional<u32> Nvnflinger::FindBufferQueueId(u64 display_id, u64 layer_id) {
181 const auto lock_guard = Lock(); 181 const auto lock_guard = Lock();
182 const auto* const layer = FindOrCreateLayer(display_id, layer_id); 182 const auto* const layer = FindOrCreateLayer(display_id, layer_id);
183 183
@@ -188,7 +188,7 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) {
188 return layer->GetBinderId(); 188 return layer->GetBinderId();
189} 189}
190 190
191ResultVal<Kernel::KReadableEvent*> NVFlinger::FindVsyncEvent(u64 display_id) { 191ResultVal<Kernel::KReadableEvent*> Nvnflinger::FindVsyncEvent(u64 display_id) {
192 const auto lock_guard = Lock(); 192 const auto lock_guard = Lock();
193 auto* const display = FindDisplay(display_id); 193 auto* const display = FindDisplay(display_id);
194 194
@@ -199,7 +199,7 @@ ResultVal<Kernel::KReadableEvent*> NVFlinger::FindVsyncEvent(u64 display_id) {
199 return display->GetVSyncEvent(); 199 return display->GetVSyncEvent();
200} 200}
201 201
202VI::Display* NVFlinger::FindDisplay(u64 display_id) { 202VI::Display* Nvnflinger::FindDisplay(u64 display_id) {
203 const auto itr = 203 const auto itr =
204 std::find_if(displays.begin(), displays.end(), 204 std::find_if(displays.begin(), displays.end(),
205 [&](const VI::Display& display) { return display.GetID() == display_id; }); 205 [&](const VI::Display& display) { return display.GetID() == display_id; });
@@ -211,7 +211,7 @@ VI::Display* NVFlinger::FindDisplay(u64 display_id) {
211 return &*itr; 211 return &*itr;
212} 212}
213 213
214const VI::Display* NVFlinger::FindDisplay(u64 display_id) const { 214const VI::Display* Nvnflinger::FindDisplay(u64 display_id) const {
215 const auto itr = 215 const auto itr =
216 std::find_if(displays.begin(), displays.end(), 216 std::find_if(displays.begin(), displays.end(),
217 [&](const VI::Display& display) { return display.GetID() == display_id; }); 217 [&](const VI::Display& display) { return display.GetID() == display_id; });
@@ -223,7 +223,7 @@ const VI::Display* NVFlinger::FindDisplay(u64 display_id) const {
223 return &*itr; 223 return &*itr;
224} 224}
225 225
226VI::Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) { 226VI::Layer* Nvnflinger::FindLayer(u64 display_id, u64 layer_id) {
227 auto* const display = FindDisplay(display_id); 227 auto* const display = FindDisplay(display_id);
228 228
229 if (display == nullptr) { 229 if (display == nullptr) {
@@ -233,7 +233,7 @@ VI::Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) {
233 return display->FindLayer(layer_id); 233 return display->FindLayer(layer_id);
234} 234}
235 235
236const VI::Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) const { 236const VI::Layer* Nvnflinger::FindLayer(u64 display_id, u64 layer_id) const {
237 const auto* const display = FindDisplay(display_id); 237 const auto* const display = FindDisplay(display_id);
238 238
239 if (display == nullptr) { 239 if (display == nullptr) {
@@ -243,7 +243,7 @@ const VI::Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) const {
243 return display->FindLayer(layer_id); 243 return display->FindLayer(layer_id);
244} 244}
245 245
246VI::Layer* NVFlinger::FindOrCreateLayer(u64 display_id, u64 layer_id) { 246VI::Layer* Nvnflinger::FindOrCreateLayer(u64 display_id, u64 layer_id) {
247 auto* const display = FindDisplay(display_id); 247 auto* const display = FindDisplay(display_id);
248 248
249 if (display == nullptr) { 249 if (display == nullptr) {
@@ -253,7 +253,7 @@ VI::Layer* NVFlinger::FindOrCreateLayer(u64 display_id, u64 layer_id) {
253 auto* layer = display->FindLayer(layer_id); 253 auto* layer = display->FindLayer(layer_id);
254 254
255 if (layer == nullptr) { 255 if (layer == nullptr) {
256 LOG_DEBUG(Service_NVFlinger, "Layer at id {} not found. Trying to create it.", layer_id); 256 LOG_DEBUG(Service_Nvnflinger, "Layer at id {} not found. Trying to create it.", layer_id);
257 CreateLayerAtId(*display, layer_id); 257 CreateLayerAtId(*display, layer_id);
258 return display->FindLayer(layer_id); 258 return display->FindLayer(layer_id);
259 } 259 }
@@ -261,7 +261,7 @@ VI::Layer* NVFlinger::FindOrCreateLayer(u64 display_id, u64 layer_id) {
261 return layer; 261 return layer;
262} 262}
263 263
264void NVFlinger::Compose() { 264void Nvnflinger::Compose() {
265 for (auto& display : displays) { 265 for (auto& display : displays) {
266 // Trigger vsync for this display at the end of drawing 266 // Trigger vsync for this display at the end of drawing
267 SCOPE_EXIT({ display.SignalVSyncEvent(); }); 267 SCOPE_EXIT({ display.SignalVSyncEvent(); });
@@ -311,7 +311,7 @@ void NVFlinger::Compose() {
311 } 311 }
312} 312}
313 313
314s64 NVFlinger::GetNextTicks() const { 314s64 Nvnflinger::GetNextTicks() const {
315 const auto& settings = Settings::values; 315 const auto& settings = Settings::values;
316 auto speed_scale = 1.f; 316 auto speed_scale = 1.f;
317 if (settings.use_multi_core.GetValue()) { 317 if (settings.use_multi_core.GetValue()) {
@@ -332,4 +332,4 @@ s64 NVFlinger::GetNextTicks() const {
332 return static_cast<s64>(speed_scale * (1000000000.f / effective_fps)); 332 return static_cast<s64>(speed_scale * (1000000000.f / effective_fps));
333} 333}
334 334
335} // namespace Service::NVFlinger 335} // namespace Service::Nvnflinger
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvnflinger/nvnflinger.h
index 3828cf272..a043cceb2 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvnflinger/nvnflinger.h
@@ -42,12 +42,12 @@ class BufferQueueCore;
42class BufferQueueProducer; 42class BufferQueueProducer;
43} // namespace Service::android 43} // namespace Service::android
44 44
45namespace Service::NVFlinger { 45namespace Service::Nvnflinger {
46 46
47class NVFlinger final { 47class Nvnflinger final {
48public: 48public:
49 explicit NVFlinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_); 49 explicit Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_);
50 ~NVFlinger(); 50 ~Nvnflinger();
51 51
52 void ShutdownLayers(); 52 void ShutdownLayers();
53 53
@@ -152,4 +152,4 @@ private:
152 HosBinderDriverServer& hos_binder_driver_server; 152 HosBinderDriverServer& hos_binder_driver_server;
153}; 153};
154 154
155} // namespace Service::NVFlinger 155} // namespace Service::Nvnflinger
diff --git a/src/core/hle/service/nvflinger/parcel.h b/src/core/hle/service/nvnflinger/parcel.h
index d1b6201e0..d1b6201e0 100644
--- a/src/core/hle/service/nvflinger/parcel.h
+++ b/src/core/hle/service/nvnflinger/parcel.h
diff --git a/src/core/hle/service/nvflinger/pixel_format.h b/src/core/hle/service/nvnflinger/pixel_format.h
index f77d0acfb..f77d0acfb 100644
--- a/src/core/hle/service/nvflinger/pixel_format.h
+++ b/src/core/hle/service/nvnflinger/pixel_format.h
diff --git a/src/core/hle/service/nvflinger/producer_listener.h b/src/core/hle/service/nvnflinger/producer_listener.h
index 6bf8aaf1e..6bf8aaf1e 100644
--- a/src/core/hle/service/nvflinger/producer_listener.h
+++ b/src/core/hle/service/nvnflinger/producer_listener.h
diff --git a/src/core/hle/service/nvflinger/status.h b/src/core/hle/service/nvnflinger/status.h
index 7af166c40..7af166c40 100644
--- a/src/core/hle/service/nvflinger/status.h
+++ b/src/core/hle/service/nvnflinger/status.h
diff --git a/src/core/hle/service/nvflinger/ui/fence.h b/src/core/hle/service/nvnflinger/ui/fence.h
index 536e8156d..536e8156d 100644
--- a/src/core/hle/service/nvflinger/ui/fence.h
+++ b/src/core/hle/service/nvnflinger/ui/fence.h
diff --git a/src/core/hle/service/nvflinger/ui/graphic_buffer.h b/src/core/hle/service/nvnflinger/ui/graphic_buffer.h
index 9a27f8f02..75d1705a8 100644
--- a/src/core/hle/service/nvflinger/ui/graphic_buffer.h
+++ b/src/core/hle/service/nvnflinger/ui/graphic_buffer.h
@@ -8,7 +8,7 @@
8 8
9#include "common/common_funcs.h" 9#include "common/common_funcs.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "core/hle/service/nvflinger/pixel_format.h" 11#include "core/hle/service/nvnflinger/pixel_format.h"
12 12
13namespace Service::android { 13namespace Service::android {
14 14
diff --git a/src/core/hle/service/nvflinger/window.h b/src/core/hle/service/nvnflinger/window.h
index 61cca5b01..61cca5b01 100644
--- a/src/core/hle/service/nvflinger/window.h
+++ b/src/core/hle/service/nvnflinger/window.h
diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp
index 530e1be3b..14ba67b4c 100644
--- a/src/core/hle/service/olsc/olsc.cpp
+++ b/src/core/hle/service/olsc/olsc.cpp
@@ -1,10 +1,10 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/ipc_helpers.h" 4#include "core/hle/service/ipc_helpers.h"
5#include "core/hle/service/olsc/olsc.h" 5#include "core/hle/service/olsc/olsc.h"
6#include "core/hle/service/server_manager.h"
6#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
7#include "core/hle/service/sm/sm.h"
8 8
9namespace Service::OLSC { 9namespace Service::OLSC {
10 10
@@ -42,7 +42,7 @@ public:
42 } 42 }
43 43
44private: 44private:
45 void Initialize(Kernel::HLERequestContext& ctx) { 45 void Initialize(HLERequestContext& ctx) {
46 LOG_WARNING(Service_OLSC, "(STUBBED) called"); 46 LOG_WARNING(Service_OLSC, "(STUBBED) called");
47 47
48 initialized = true; 48 initialized = true;
@@ -51,7 +51,7 @@ private:
51 rb.Push(ResultSuccess); 51 rb.Push(ResultSuccess);
52 } 52 }
53 53
54 void GetSaveDataBackupSetting(Kernel::HLERequestContext& ctx) { 54 void GetSaveDataBackupSetting(HLERequestContext& ctx) {
55 LOG_WARNING(Service_OLSC, "(STUBBED) called"); 55 LOG_WARNING(Service_OLSC, "(STUBBED) called");
56 56
57 // backup_setting is set to 0 since real value is unknown 57 // backup_setting is set to 0 since real value is unknown
@@ -62,7 +62,7 @@ private:
62 rb.Push(backup_setting); 62 rb.Push(backup_setting);
63 } 63 }
64 64
65 void SetSaveDataBackupSettingEnabled(Kernel::HLERequestContext& ctx) { 65 void SetSaveDataBackupSettingEnabled(HLERequestContext& ctx) {
66 LOG_WARNING(Service_OLSC, "(STUBBED) called"); 66 LOG_WARNING(Service_OLSC, "(STUBBED) called");
67 67
68 IPC::ResponseBuilder rb{ctx, 2}; 68 IPC::ResponseBuilder rb{ctx, 2};
@@ -72,8 +72,11 @@ private:
72 bool initialized{}; 72 bool initialized{};
73}; 73};
74 74
75void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 75void LoopProcess(Core::System& system) {
76 std::make_shared<OLSC>(system)->InstallAsService(service_manager); 76 auto server_manager = std::make_unique<ServerManager>(system);
77
78 server_manager->RegisterNamedService("olsc:u", std::make_shared<OLSC>(system));
79 ServerManager::RunServer(std::move(server_manager));
77} 80}
78 81
79} // namespace Service::OLSC 82} // namespace Service::OLSC
diff --git a/src/core/hle/service/olsc/olsc.h b/src/core/hle/service/olsc/olsc.h
index 1522d8d32..620b634fa 100644
--- a/src/core/hle/service/olsc/olsc.h
+++ b/src/core/hle/service/olsc/olsc.h
@@ -7,13 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::OLSC { 10namespace Service::OLSC {
15 11
16/// Registers all SSL services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::OLSC 14} // namespace Service::OLSC
diff --git a/src/core/hle/service/pcie/pcie.cpp b/src/core/hle/service/pcie/pcie.cpp
index 79501b9f9..c6da6eb51 100644
--- a/src/core/hle/service/pcie/pcie.cpp
+++ b/src/core/hle/service/pcie/pcie.cpp
@@ -4,8 +4,8 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/pcie/pcie.h" 6#include "core/hle/service/pcie/pcie.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::PCIe { 10namespace Service::PCIe {
11 11
@@ -59,8 +59,11 @@ public:
59 } 59 }
60}; 60};
61 61
62void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 62void LoopProcess(Core::System& system) {
63 std::make_shared<PCIe>(system)->InstallAsService(sm); 63 auto server_manager = std::make_unique<ServerManager>(system);
64
65 server_manager->RegisterNamedService("pcie", std::make_shared<PCIe>(system));
66 ServerManager::RunServer(std::move(server_manager));
64} 67}
65 68
66} // namespace Service::PCIe 69} // namespace Service::PCIe
diff --git a/src/core/hle/service/pcie/pcie.h b/src/core/hle/service/pcie/pcie.h
index cebfd9042..5c2d4b805 100644
--- a/src/core/hle/service/pcie/pcie.h
+++ b/src/core/hle/service/pcie/pcie.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::PCIe { 10namespace Service::PCIe {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::PCIe 14} // namespace Service::PCIe
diff --git a/src/core/hle/service/pctl/pctl_module.cpp b/src/core/hle/service/pctl/pctl_module.cpp
index 083609b34..f966c5c8b 100644
--- a/src/core/hle/service/pctl/pctl_module.cpp
+++ b/src/core/hle/service/pctl/pctl_module.cpp
@@ -5,9 +5,10 @@
5#include "core/core.h" 5#include "core/core.h"
6#include "core/file_sys/control_metadata.h" 6#include "core/file_sys/control_metadata.h"
7#include "core/file_sys/patch_manager.h" 7#include "core/file_sys/patch_manager.h"
8#include "core/hle/ipc_helpers.h" 8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/pctl/pctl.h" 9#include "core/hle/service/pctl/pctl.h"
10#include "core/hle/service/pctl/pctl_module.h" 10#include "core/hle/service/pctl/pctl_module.h"
11#include "core/hle/service/server_manager.h"
11 12
12namespace Service::PCTL { 13namespace Service::PCTL {
13 14
@@ -176,7 +177,7 @@ private:
176 settings.is_stero_vision_restricted = is_restricted; 177 settings.is_stero_vision_restricted = is_restricted;
177 } 178 }
178 179
179 void Initialize(Kernel::HLERequestContext& ctx) { 180 void Initialize(HLERequestContext& ctx) {
180 LOG_DEBUG(Service_PCTL, "called"); 181 LOG_DEBUG(Service_PCTL, "called");
181 IPC::ResponseBuilder rb{ctx, 2}; 182 IPC::ResponseBuilder rb{ctx, 2};
182 183
@@ -214,7 +215,7 @@ private:
214 rb.Push(ResultSuccess); 215 rb.Push(ResultSuccess);
215 } 216 }
216 217
217 void CheckFreeCommunicationPermission(Kernel::HLERequestContext& ctx) { 218 void CheckFreeCommunicationPermission(HLERequestContext& ctx) {
218 LOG_DEBUG(Service_PCTL, "called"); 219 LOG_DEBUG(Service_PCTL, "called");
219 220
220 IPC::ResponseBuilder rb{ctx, 2}; 221 IPC::ResponseBuilder rb{ctx, 2};
@@ -227,7 +228,7 @@ private:
227 states.free_communication = true; 228 states.free_communication = true;
228 } 229 }
229 230
230 void ConfirmStereoVisionPermission(Kernel::HLERequestContext& ctx) { 231 void ConfirmStereoVisionPermission(HLERequestContext& ctx) {
231 LOG_DEBUG(Service_PCTL, "called"); 232 LOG_DEBUG(Service_PCTL, "called");
232 states.stereo_vision = true; 233 states.stereo_vision = true;
233 234
@@ -235,14 +236,14 @@ private:
235 rb.Push(ResultSuccess); 236 rb.Push(ResultSuccess);
236 } 237 }
237 238
238 void EndFreeCommunication(Kernel::HLERequestContext& ctx) { 239 void EndFreeCommunication(HLERequestContext& ctx) {
239 LOG_WARNING(Service_PCTL, "(STUBBED) called"); 240 LOG_WARNING(Service_PCTL, "(STUBBED) called");
240 241
241 IPC::ResponseBuilder rb{ctx, 2}; 242 IPC::ResponseBuilder rb{ctx, 2};
242 rb.Push(ResultSuccess); 243 rb.Push(ResultSuccess);
243 } 244 }
244 245
245 void IsFreeCommunicationAvailable(Kernel::HLERequestContext& ctx) { 246 void IsFreeCommunicationAvailable(HLERequestContext& ctx) {
246 LOG_WARNING(Service_PCTL, "(STUBBED) called"); 247 LOG_WARNING(Service_PCTL, "(STUBBED) called");
247 248
248 IPC::ResponseBuilder rb{ctx, 2}; 249 IPC::ResponseBuilder rb{ctx, 2};
@@ -253,7 +254,7 @@ private:
253 } 254 }
254 } 255 }
255 256
256 void IsRestrictionEnabled(Kernel::HLERequestContext& ctx) { 257 void IsRestrictionEnabled(HLERequestContext& ctx) {
257 LOG_DEBUG(Service_PCTL, "called"); 258 LOG_DEBUG(Service_PCTL, "called");
258 259
259 IPC::ResponseBuilder rb{ctx, 3}; 260 IPC::ResponseBuilder rb{ctx, 3};
@@ -267,7 +268,7 @@ private:
267 rb.Push(pin_code[0] != '\0'); 268 rb.Push(pin_code[0] != '\0');
268 } 269 }
269 270
270 void ConfirmStereoVisionRestrictionConfigurable(Kernel::HLERequestContext& ctx) { 271 void ConfirmStereoVisionRestrictionConfigurable(HLERequestContext& ctx) {
271 LOG_DEBUG(Service_PCTL, "called"); 272 LOG_DEBUG(Service_PCTL, "called");
272 273
273 IPC::ResponseBuilder rb{ctx, 2}; 274 IPC::ResponseBuilder rb{ctx, 2};
@@ -286,7 +287,7 @@ private:
286 rb.Push(ResultSuccess); 287 rb.Push(ResultSuccess);
287 } 288 }
288 289
289 void IsStereoVisionPermitted(Kernel::HLERequestContext& ctx) { 290 void IsStereoVisionPermitted(HLERequestContext& ctx) {
290 LOG_DEBUG(Service_PCTL, "called"); 291 LOG_DEBUG(Service_PCTL, "called");
291 292
292 IPC::ResponseBuilder rb{ctx, 3}; 293 IPC::ResponseBuilder rb{ctx, 3};
@@ -299,7 +300,7 @@ private:
299 } 300 }
300 } 301 }
301 302
302 void SetStereoVisionRestriction(Kernel::HLERequestContext& ctx) { 303 void SetStereoVisionRestriction(HLERequestContext& ctx) {
303 IPC::RequestParser rp{ctx}; 304 IPC::RequestParser rp{ctx};
304 const auto can_use = rp.Pop<bool>(); 305 const auto can_use = rp.Pop<bool>();
305 LOG_DEBUG(Service_PCTL, "called, can_use={}", can_use); 306 LOG_DEBUG(Service_PCTL, "called, can_use={}", can_use);
@@ -315,7 +316,7 @@ private:
315 rb.Push(ResultSuccess); 316 rb.Push(ResultSuccess);
316 } 317 }
317 318
318 void GetStereoVisionRestriction(Kernel::HLERequestContext& ctx) { 319 void GetStereoVisionRestriction(HLERequestContext& ctx) {
319 LOG_DEBUG(Service_PCTL, "called"); 320 LOG_DEBUG(Service_PCTL, "called");
320 321
321 IPC::ResponseBuilder rb{ctx, 3}; 322 IPC::ResponseBuilder rb{ctx, 3};
@@ -330,7 +331,7 @@ private:
330 rb.Push(settings.is_stero_vision_restricted); 331 rb.Push(settings.is_stero_vision_restricted);
331 } 332 }
332 333
333 void ResetConfirmedStereoVisionPermission(Kernel::HLERequestContext& ctx) { 334 void ResetConfirmedStereoVisionPermission(HLERequestContext& ctx) {
334 LOG_DEBUG(Service_PCTL, "called"); 335 LOG_DEBUG(Service_PCTL, "called");
335 336
336 states.stereo_vision = false; 337 states.stereo_vision = false;
@@ -369,7 +370,7 @@ private:
369 Capability capability{}; 370 Capability capability{};
370}; 371};
371 372
372void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) { 373void Module::Interface::CreateService(HLERequestContext& ctx) {
373 LOG_DEBUG(Service_PCTL, "called"); 374 LOG_DEBUG(Service_PCTL, "called");
374 375
375 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 376 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -379,7 +380,7 @@ void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) {
379 rb.PushIpcInterface<IParentalControlService>(system, capability); 380 rb.PushIpcInterface<IParentalControlService>(system, capability);
380} 381}
381 382
382void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) { 383void Module::Interface::CreateServiceWithoutInitialize(HLERequestContext& ctx) {
383 LOG_DEBUG(Service_PCTL, "called"); 384 LOG_DEBUG(Service_PCTL, "called");
384 385
385 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 386 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -393,19 +394,22 @@ Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> modu
393 394
394Module::Interface::~Interface() = default; 395Module::Interface::~Interface() = default;
395 396
396void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 397void LoopProcess(Core::System& system) {
398 auto server_manager = std::make_unique<ServerManager>(system);
399
397 auto module = std::make_shared<Module>(); 400 auto module = std::make_shared<Module>();
398 std::make_shared<PCTL>(system, module, "pctl", 401 server_manager->RegisterNamedService(
399 Capability::Application | Capability::SnsPost | Capability::Status | 402 "pctl", std::make_shared<PCTL>(system, module, "pctl",
400 Capability::StereoVision) 403 Capability::Application | Capability::SnsPost |
401 ->InstallAsService(service_manager); 404 Capability::Status | Capability::StereoVision));
402 // TODO(ogniK): Implement remaining capabilities 405 // TODO(ogniK): Implement remaining capabilities
403 std::make_shared<PCTL>(system, module, "pctl:a", Capability::None) 406 server_manager->RegisterNamedService(
404 ->InstallAsService(service_manager); 407 "pctl:a", std::make_shared<PCTL>(system, module, "pctl:a", Capability::None));
405 std::make_shared<PCTL>(system, module, "pctl:r", Capability::None) 408 server_manager->RegisterNamedService(
406 ->InstallAsService(service_manager); 409 "pctl:r", std::make_shared<PCTL>(system, module, "pctl:r", Capability::None));
407 std::make_shared<PCTL>(system, module, "pctl:s", Capability::None) 410 server_manager->RegisterNamedService(
408 ->InstallAsService(service_manager); 411 "pctl:s", std::make_shared<PCTL>(system, module, "pctl:s", Capability::None));
412 ServerManager::RunServer(std::move(server_manager));
409} 413}
410 414
411} // namespace Service::PCTL 415} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/pctl_module.h b/src/core/hle/service/pctl/pctl_module.h
index 6f584530d..dff0d3f08 100644
--- a/src/core/hle/service/pctl/pctl_module.h
+++ b/src/core/hle/service/pctl/pctl_module.h
@@ -31,8 +31,8 @@ public:
31 const char* name_, Capability capability_); 31 const char* name_, Capability capability_);
32 ~Interface() override; 32 ~Interface() override;
33 33
34 void CreateService(Kernel::HLERequestContext& ctx); 34 void CreateService(HLERequestContext& ctx);
35 void CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx); 35 void CreateServiceWithoutInitialize(HLERequestContext& ctx);
36 36
37 protected: 37 protected:
38 std::shared_ptr<Module> module; 38 std::shared_ptr<Module> module;
@@ -42,7 +42,6 @@ public:
42 }; 42 };
43}; 43};
44 44
45/// Registers all PCTL services with the specified service manager. 45void LoopProcess(Core::System& system);
46void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
47 46
48} // namespace Service::PCTL 47} // namespace Service::PCTL
diff --git a/src/core/hle/service/pcv/pcv.cpp b/src/core/hle/service/pcv/pcv.cpp
index 98037a8d4..c13ffa6f6 100644
--- a/src/core/hle/service/pcv/pcv.cpp
+++ b/src/core/hle/service/pcv/pcv.cpp
@@ -3,10 +3,10 @@
3 3
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/ipc_helpers.h" 6#include "core/hle/service/ipc_helpers.h"
7#include "core/hle/service/pcv/pcv.h" 7#include "core/hle/service/pcv/pcv.h"
8#include "core/hle/service/server_manager.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10 10
11namespace Service::PCV { 11namespace Service::PCV {
12 12
@@ -76,7 +76,7 @@ public:
76 } 76 }
77 77
78private: 78private:
79 void SetClockRate(Kernel::HLERequestContext& ctx) { 79 void SetClockRate(HLERequestContext& ctx) {
80 IPC::RequestParser rp{ctx}; 80 IPC::RequestParser rp{ctx};
81 clock_rate = rp.Pop<u32>(); 81 clock_rate = rp.Pop<u32>();
82 LOG_DEBUG(Service_PCV, "(STUBBED) called, clock_rate={}", clock_rate); 82 LOG_DEBUG(Service_PCV, "(STUBBED) called, clock_rate={}", clock_rate);
@@ -85,7 +85,7 @@ private:
85 rb.Push(ResultSuccess); 85 rb.Push(ResultSuccess);
86 } 86 }
87 87
88 void GetClockRate(Kernel::HLERequestContext& ctx) { 88 void GetClockRate(HLERequestContext& ctx) {
89 LOG_DEBUG(Service_PCV, "(STUBBED) called"); 89 LOG_DEBUG(Service_PCV, "(STUBBED) called");
90 90
91 IPC::ResponseBuilder rb{ctx, 3}; 91 IPC::ResponseBuilder rb{ctx, 3};
@@ -115,7 +115,7 @@ public:
115 } 115 }
116 116
117private: 117private:
118 void OpenSession(Kernel::HLERequestContext& ctx) { 118 void OpenSession(HLERequestContext& ctx) {
119 IPC::RequestParser rp{ctx}; 119 IPC::RequestParser rp{ctx};
120 const auto device_code = static_cast<DeviceCode>(rp.Pop<u32>()); 120 const auto device_code = static_cast<DeviceCode>(rp.Pop<u32>());
121 const auto unkonwn_input = rp.Pop<u32>(); 121 const auto unkonwn_input = rp.Pop<u32>();
@@ -141,11 +141,14 @@ public:
141 } 141 }
142}; 142};
143 143
144void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 144void LoopProcess(Core::System& system) {
145 std::make_shared<PCV>(system)->InstallAsService(sm); 145 auto server_manager = std::make_unique<ServerManager>(system);
146 std::make_shared<CLKRST>(system, "clkrst")->InstallAsService(sm); 146
147 std::make_shared<CLKRST>(system, "clkrst:i")->InstallAsService(sm); 147 server_manager->RegisterNamedService("pcv", std::make_shared<PCV>(system));
148 std::make_shared<CLKRST_A>(system)->InstallAsService(sm); 148 server_manager->RegisterNamedService("clkrst", std::make_shared<CLKRST>(system, "clkrst"));
149 server_manager->RegisterNamedService("clkrst:i", std::make_shared<CLKRST>(system, "clkrst:i"));
150 server_manager->RegisterNamedService("clkrst:a", std::make_shared<CLKRST_A>(system));
151 ServerManager::RunServer(std::move(server_manager));
149} 152}
150 153
151} // namespace Service::PCV 154} // namespace Service::PCV
diff --git a/src/core/hle/service/pcv/pcv.h b/src/core/hle/service/pcv/pcv.h
index 6b26b6fa7..bf541e6fe 100644
--- a/src/core/hle/service/pcv/pcv.h
+++ b/src/core/hle/service/pcv/pcv.h
@@ -7,10 +7,6 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::PCV { 10namespace Service::PCV {
15 11
16enum class DeviceCode : u32 { 12enum class DeviceCode : u32 {
@@ -104,6 +100,6 @@ enum class DeviceCode : u32 {
104 OscClk = 0x40000080 100 OscClk = 0x40000080
105}; 101};
106 102
107void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 103void LoopProcess(Core::System& system);
108 104
109} // namespace Service::PCV 105} // namespace Service::PCV
diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp
index b10e86c8f..ea249c26f 100644
--- a/src/core/hle/service/pm/pm.cpp
+++ b/src/core/hle/service/pm/pm.cpp
@@ -2,10 +2,11 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/kernel/k_process.h" 5#include "core/hle/kernel/k_process.h"
7#include "core/hle/kernel/kernel.h" 6#include "core/hle/kernel/kernel.h"
7#include "core/hle/service/ipc_helpers.h"
8#include "core/hle/service/pm/pm.h" 8#include "core/hle/service/pm/pm.h"
9#include "core/hle/service/server_manager.h"
9#include "core/hle/service/service.h" 10#include "core/hle/service/service.h"
10 11
11namespace Service::PM { 12namespace Service::PM {
@@ -33,7 +34,7 @@ std::optional<Kernel::KProcess*> SearchProcessList(
33 return *iter; 34 return *iter;
34} 35}
35 36
36void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx, 37void GetApplicationPidGeneric(HLERequestContext& ctx,
37 const std::vector<Kernel::KProcess*>& process_list) { 38 const std::vector<Kernel::KProcess*>& process_list) {
38 const auto process = SearchProcessList(process_list, [](const auto& proc) { 39 const auto process = SearchProcessList(process_list, [](const auto& proc) {
39 return proc->GetProcessID() == Kernel::KProcess::ProcessIDMin; 40 return proc->GetProcessID() == Kernel::KProcess::ProcessIDMin;
@@ -57,7 +58,7 @@ public:
57 } 58 }
58 59
59private: 60private:
60 void GetBootMode(Kernel::HLERequestContext& ctx) { 61 void GetBootMode(HLERequestContext& ctx) {
61 LOG_DEBUG(Service_PM, "called"); 62 LOG_DEBUG(Service_PM, "called");
62 63
63 IPC::ResponseBuilder rb{ctx, 3}; 64 IPC::ResponseBuilder rb{ctx, 3};
@@ -65,7 +66,7 @@ private:
65 rb.PushEnum(boot_mode); 66 rb.PushEnum(boot_mode);
66 } 67 }
67 68
68 void SetMaintenanceBoot(Kernel::HLERequestContext& ctx) { 69 void SetMaintenanceBoot(HLERequestContext& ctx) {
69 LOG_DEBUG(Service_PM, "called"); 70 LOG_DEBUG(Service_PM, "called");
70 71
71 boot_mode = SystemBootMode::Maintenance; 72 boot_mode = SystemBootMode::Maintenance;
@@ -99,7 +100,7 @@ public:
99 } 100 }
100 101
101private: 102private:
102 void GetProcessId(Kernel::HLERequestContext& ctx) { 103 void GetProcessId(HLERequestContext& ctx) {
103 IPC::RequestParser rp{ctx}; 104 IPC::RequestParser rp{ctx};
104 const auto program_id = rp.PopRaw<u64>(); 105 const auto program_id = rp.PopRaw<u64>();
105 106
@@ -121,12 +122,12 @@ private:
121 rb.Push((*process)->GetProcessID()); 122 rb.Push((*process)->GetProcessID());
122 } 123 }
123 124
124 void GetApplicationProcessId(Kernel::HLERequestContext& ctx) { 125 void GetApplicationProcessId(HLERequestContext& ctx) {
125 LOG_DEBUG(Service_PM, "called"); 126 LOG_DEBUG(Service_PM, "called");
126 GetApplicationPidGeneric(ctx, kernel.GetProcessList()); 127 GetApplicationPidGeneric(ctx, kernel.GetProcessList());
127 } 128 }
128 129
129 void AtmosphereGetProcessInfo(Kernel::HLERequestContext& ctx) { 130 void AtmosphereGetProcessInfo(HLERequestContext& ctx) {
130 // https://github.com/Atmosphere-NX/Atmosphere/blob/master/stratosphere/pm/source/impl/pm_process_manager.cpp#L614 131 // https://github.com/Atmosphere-NX/Atmosphere/blob/master/stratosphere/pm/source/impl/pm_process_manager.cpp#L614
131 // This implementation is incomplete; only a handle to the process is returned. 132 // This implementation is incomplete; only a handle to the process is returned.
132 IPC::RequestParser rp{ctx}; 133 IPC::RequestParser rp{ctx};
@@ -186,7 +187,7 @@ public:
186 } 187 }
187 188
188private: 189private:
189 void GetProgramId(Kernel::HLERequestContext& ctx) { 190 void GetProgramId(HLERequestContext& ctx) {
190 IPC::RequestParser rp{ctx}; 191 IPC::RequestParser rp{ctx};
191 const auto process_id = rp.PopRaw<u64>(); 192 const auto process_id = rp.PopRaw<u64>();
192 193
@@ -207,7 +208,7 @@ private:
207 rb.Push((*process)->GetProgramID()); 208 rb.Push((*process)->GetProgramID());
208 } 209 }
209 210
210 void AtmosphereGetProcessId(Kernel::HLERequestContext& ctx) { 211 void AtmosphereGetProcessId(HLERequestContext& ctx) {
211 IPC::RequestParser rp{ctx}; 212 IPC::RequestParser rp{ctx};
212 const auto program_id = rp.PopRaw<u64>(); 213 const auto program_id = rp.PopRaw<u64>();
213 214
@@ -254,7 +255,7 @@ public:
254 } 255 }
255 256
256private: 257private:
257 void GetApplicationProcessIdForShell(Kernel::HLERequestContext& ctx) { 258 void GetApplicationProcessIdForShell(HLERequestContext& ctx) {
258 LOG_DEBUG(Service_PM, "called"); 259 LOG_DEBUG(Service_PM, "called");
259 GetApplicationPidGeneric(ctx, kernel.GetProcessList()); 260 GetApplicationPidGeneric(ctx, kernel.GetProcessList());
260 } 261 }
@@ -262,12 +263,15 @@ private:
262 const Kernel::KernelCore& kernel; 263 const Kernel::KernelCore& kernel;
263}; 264};
264 265
265void InstallInterfaces(Core::System& system) { 266void LoopProcess(Core::System& system) {
266 std::make_shared<BootMode>(system)->InstallAsService(system.ServiceManager()); 267 auto server_manager = std::make_unique<ServerManager>(system);
267 std::make_shared<DebugMonitor>(system)->InstallAsService(system.ServiceManager()); 268
268 std::make_shared<Info>(system, system.Kernel().GetProcessList()) 269 server_manager->RegisterNamedService("pm:bm", std::make_shared<BootMode>(system));
269 ->InstallAsService(system.ServiceManager()); 270 server_manager->RegisterNamedService("pm:dmnt", std::make_shared<DebugMonitor>(system));
270 std::make_shared<Shell>(system)->InstallAsService(system.ServiceManager()); 271 server_manager->RegisterNamedService(
272 "pm:info", std::make_shared<Info>(system, system.Kernel().GetProcessList()));
273 server_manager->RegisterNamedService("pm:shell", std::make_shared<Shell>(system));
274 ServerManager::RunServer(std::move(server_manager));
271} 275}
272 276
273} // namespace Service::PM 277} // namespace Service::PM
diff --git a/src/core/hle/service/pm/pm.h b/src/core/hle/service/pm/pm.h
index 060103928..5d4a1a171 100644
--- a/src/core/hle/service/pm/pm.h
+++ b/src/core/hle/service/pm/pm.h
@@ -14,7 +14,6 @@ enum class SystemBootMode {
14 Maintenance, 14 Maintenance,
15}; 15};
16 16
17/// Registers all PM services with the specified service manager. 17void LoopProcess(Core::System& system);
18void InstallInterfaces(Core::System& system);
19 18
20} // namespace Service::PM 19} // namespace Service::PM
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp
index 90c5f8756..ec4a84989 100644
--- a/src/core/hle/service/prepo/prepo.cpp
+++ b/src/core/hle/service/prepo/prepo.cpp
@@ -4,9 +4,10 @@
4#include "common/hex_util.h" 4#include "common/hex_util.h"
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "core/core.h" 6#include "core/core.h"
7#include "core/hle/ipc_helpers.h"
8#include "core/hle/service/acc/profile_manager.h" 7#include "core/hle/service/acc/profile_manager.h"
8#include "core/hle/service/ipc_helpers.h"
9#include "core/hle/service/prepo/prepo.h" 9#include "core/hle/service/prepo/prepo.h"
10#include "core/hle/service/server_manager.h"
10#include "core/hle/service/service.h" 11#include "core/hle/service/service.h"
11#include "core/reporter.h" 12#include "core/reporter.h"
12 13
@@ -53,7 +54,7 @@ public:
53 54
54private: 55private:
55 template <Core::Reporter::PlayReportType Type> 56 template <Core::Reporter::PlayReportType Type>
56 void SaveReport(Kernel::HLERequestContext& ctx) { 57 void SaveReport(HLERequestContext& ctx) {
57 IPC::RequestParser rp{ctx}; 58 IPC::RequestParser rp{ctx};
58 const auto process_id = rp.PopRaw<u64>(); 59 const auto process_id = rp.PopRaw<u64>();
59 60
@@ -79,7 +80,7 @@ private:
79 } 80 }
80 81
81 template <Core::Reporter::PlayReportType Type> 82 template <Core::Reporter::PlayReportType Type>
82 void SaveReportWithUser(Kernel::HLERequestContext& ctx) { 83 void SaveReportWithUser(HLERequestContext& ctx) {
83 IPC::RequestParser rp{ctx}; 84 IPC::RequestParser rp{ctx};
84 const auto user_id = rp.PopRaw<u128>(); 85 const auto user_id = rp.PopRaw<u128>();
85 const auto process_id = rp.PopRaw<u64>(); 86 const auto process_id = rp.PopRaw<u64>();
@@ -106,14 +107,14 @@ private:
106 rb.Push(ResultSuccess); 107 rb.Push(ResultSuccess);
107 } 108 }
108 109
109 void RequestImmediateTransmission(Kernel::HLERequestContext& ctx) { 110 void RequestImmediateTransmission(HLERequestContext& ctx) {
110 LOG_WARNING(Service_PREPO, "(STUBBED) called"); 111 LOG_WARNING(Service_PREPO, "(STUBBED) called");
111 112
112 IPC::ResponseBuilder rb{ctx, 2}; 113 IPC::ResponseBuilder rb{ctx, 2};
113 rb.Push(ResultSuccess); 114 rb.Push(ResultSuccess);
114 } 115 }
115 116
116 void GetTransmissionStatus(Kernel::HLERequestContext& ctx) { 117 void GetTransmissionStatus(HLERequestContext& ctx) {
117 LOG_WARNING(Service_PREPO, "(STUBBED) called"); 118 LOG_WARNING(Service_PREPO, "(STUBBED) called");
118 119
119 constexpr s32 status = 0; 120 constexpr s32 status = 0;
@@ -123,7 +124,7 @@ private:
123 rb.Push(status); 124 rb.Push(status);
124 } 125 }
125 126
126 void GetSystemSessionId(Kernel::HLERequestContext& ctx) { 127 void GetSystemSessionId(HLERequestContext& ctx) {
127 LOG_WARNING(Service_PREPO, "(STUBBED) called"); 128 LOG_WARNING(Service_PREPO, "(STUBBED) called");
128 129
129 constexpr u64 system_session_id = 0; 130 constexpr u64 system_session_id = 0;
@@ -132,7 +133,7 @@ private:
132 rb.Push(system_session_id); 133 rb.Push(system_session_id);
133 } 134 }
134 135
135 void SaveSystemReport(Kernel::HLERequestContext& ctx) { 136 void SaveSystemReport(HLERequestContext& ctx) {
136 IPC::RequestParser rp{ctx}; 137 IPC::RequestParser rp{ctx};
137 const auto title_id = rp.PopRaw<u64>(); 138 const auto title_id = rp.PopRaw<u64>();
138 139
@@ -155,7 +156,7 @@ private:
155 rb.Push(ResultSuccess); 156 rb.Push(ResultSuccess);
156 } 157 }
157 158
158 void SaveSystemReportWithUser(Kernel::HLERequestContext& ctx) { 159 void SaveSystemReportWithUser(HLERequestContext& ctx) {
159 IPC::RequestParser rp{ctx}; 160 IPC::RequestParser rp{ctx};
160 const auto user_id = rp.PopRaw<u128>(); 161 const auto user_id = rp.PopRaw<u128>();
161 const auto title_id = rp.PopRaw<u64>(); 162 const auto title_id = rp.PopRaw<u64>();
@@ -183,12 +184,20 @@ private:
183 } 184 }
184}; 185};
185 186
186void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 187void LoopProcess(Core::System& system) {
187 std::make_shared<PlayReport>("prepo:a", system)->InstallAsService(service_manager); 188 auto server_manager = std::make_unique<ServerManager>(system);
188 std::make_shared<PlayReport>("prepo:a2", system)->InstallAsService(service_manager); 189
189 std::make_shared<PlayReport>("prepo:m", system)->InstallAsService(service_manager); 190 server_manager->RegisterNamedService("prepo:a",
190 std::make_shared<PlayReport>("prepo:s", system)->InstallAsService(service_manager); 191 std::make_shared<PlayReport>("prepo:a", system));
191 std::make_shared<PlayReport>("prepo:u", system)->InstallAsService(service_manager); 192 server_manager->RegisterNamedService("prepo:a2",
193 std::make_shared<PlayReport>("prepo:a2", system));
194 server_manager->RegisterNamedService("prepo:m",
195 std::make_shared<PlayReport>("prepo:m", system));
196 server_manager->RegisterNamedService("prepo:s",
197 std::make_shared<PlayReport>("prepo:s", system));
198 server_manager->RegisterNamedService("prepo:u",
199 std::make_shared<PlayReport>("prepo:u", system));
200 ServerManager::RunServer(std::move(server_manager));
192} 201}
193 202
194} // namespace Service::PlayReport 203} // namespace Service::PlayReport
diff --git a/src/core/hle/service/prepo/prepo.h b/src/core/hle/service/prepo/prepo.h
index 37ea5afad..2c2462f93 100644
--- a/src/core/hle/service/prepo/prepo.h
+++ b/src/core/hle/service/prepo/prepo.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::PlayReport { 10namespace Service::PlayReport {
15 11
16void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::PlayReport 14} // namespace Service::PlayReport
diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp
index 3a9412cf5..cd0cc9287 100644
--- a/src/core/hle/service/psc/psc.cpp
+++ b/src/core/hle/service/psc/psc.cpp
@@ -4,16 +4,16 @@
4#include <memory> 4#include <memory>
5 5
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/hle/ipc_helpers.h" 7#include "core/hle/service/ipc_helpers.h"
8#include "core/hle/service/psc/psc.h" 8#include "core/hle/service/psc/psc.h"
9#include "core/hle/service/server_manager.h"
9#include "core/hle/service/service.h" 10#include "core/hle/service/service.h"
10#include "core/hle/service/sm/sm.h"
11 11
12namespace Service::PSC { 12namespace Service::PSC {
13 13
14class PSC_C final : public ServiceFramework<PSC_C> { 14class IPmControl final : public ServiceFramework<IPmControl> {
15public: 15public:
16 explicit PSC_C(Core::System& system_) : ServiceFramework{system_, "psc:c"} { 16 explicit IPmControl(Core::System& system_) : ServiceFramework{system_, "psc:c"} {
17 // clang-format off 17 // clang-format off
18 static const FunctionInfo functions[] = { 18 static const FunctionInfo functions[] = {
19 {0, nullptr, "Initialize"}, 19 {0, nullptr, "Initialize"},
@@ -23,8 +23,8 @@ public:
23 {4, nullptr, "Cancel"}, 23 {4, nullptr, "Cancel"},
24 {5, nullptr, "PrintModuleInformation"}, 24 {5, nullptr, "PrintModuleInformation"},
25 {6, nullptr, "GetModuleInformation"}, 25 {6, nullptr, "GetModuleInformation"},
26 {10, nullptr, "Unknown10"}, 26 {10, nullptr, "AcquireStateLock"},
27 {11, nullptr, "Unknown11"}, 27 {11, nullptr, "HasStateLock"},
28 }; 28 };
29 // clang-format on 29 // clang-format on
30 30
@@ -49,12 +49,12 @@ public:
49 } 49 }
50}; 50};
51 51
52class PSC_M final : public ServiceFramework<PSC_M> { 52class IPmService final : public ServiceFramework<IPmService> {
53public: 53public:
54 explicit PSC_M(Core::System& system_) : ServiceFramework{system_, "psc:m"} { 54 explicit IPmService(Core::System& system_) : ServiceFramework{system_, "psc:m"} {
55 // clang-format off 55 // clang-format off
56 static const FunctionInfo functions[] = { 56 static const FunctionInfo functions[] = {
57 {0, &PSC_M::GetPmModule, "GetPmModule"}, 57 {0, &IPmService::GetPmModule, "GetPmModule"},
58 }; 58 };
59 // clang-format on 59 // clang-format on
60 60
@@ -62,7 +62,7 @@ public:
62 } 62 }
63 63
64private: 64private:
65 void GetPmModule(Kernel::HLERequestContext& ctx) { 65 void GetPmModule(HLERequestContext& ctx) {
66 LOG_DEBUG(Service_PSC, "called"); 66 LOG_DEBUG(Service_PSC, "called");
67 67
68 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 68 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -71,9 +71,12 @@ private:
71 } 71 }
72}; 72};
73 73
74void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 74void LoopProcess(Core::System& system) {
75 std::make_shared<PSC_C>(system)->InstallAsService(sm); 75 auto server_manager = std::make_unique<ServerManager>(system);
76 std::make_shared<PSC_M>(system)->InstallAsService(sm); 76
77 server_manager->RegisterNamedService("psc:c", std::make_shared<IPmControl>(system));
78 server_manager->RegisterNamedService("psc:m", std::make_shared<IPmService>(system));
79 ServerManager::RunServer(std::move(server_manager));
77} 80}
78 81
79} // namespace Service::PSC 82} // namespace Service::PSC
diff --git a/src/core/hle/service/psc/psc.h b/src/core/hle/service/psc/psc.h
index d248372c2..459137f42 100644
--- a/src/core/hle/service/psc/psc.h
+++ b/src/core/hle/service/psc/psc.h
@@ -13,6 +13,6 @@ class ServiceManager;
13 13
14namespace Service::PSC { 14namespace Service::PSC {
15 15
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 16void LoopProcess(Core::System& system);
17 17
18} // namespace Service::PSC 18} // namespace Service::PSC
diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp
index 1ac97fe31..136313d7b 100644
--- a/src/core/hle/service/ptm/psm.cpp
+++ b/src/core/hle/service/ptm/psm.cpp
@@ -5,8 +5,8 @@
5 5
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core.h" 7#include "core/core.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/k_event.h" 8#include "core/hle/kernel/k_event.h"
9#include "core/hle/service/ipc_helpers.h"
10#include "core/hle/service/kernel_helpers.h" 10#include "core/hle/service/kernel_helpers.h"
11#include "core/hle/service/ptm/psm.h" 11#include "core/hle/service/ptm/psm.h"
12 12
@@ -54,7 +54,7 @@ public:
54 } 54 }
55 55
56private: 56private:
57 void BindStateChangeEvent(Kernel::HLERequestContext& ctx) { 57 void BindStateChangeEvent(HLERequestContext& ctx) {
58 LOG_DEBUG(Service_PTM, "called"); 58 LOG_DEBUG(Service_PTM, "called");
59 59
60 should_signal = true; 60 should_signal = true;
@@ -64,7 +64,7 @@ private:
64 rb.PushCopyObjects(state_change_event->GetReadableEvent()); 64 rb.PushCopyObjects(state_change_event->GetReadableEvent());
65 } 65 }
66 66
67 void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) { 67 void UnbindStateChangeEvent(HLERequestContext& ctx) {
68 LOG_DEBUG(Service_PTM, "called"); 68 LOG_DEBUG(Service_PTM, "called");
69 69
70 should_signal = false; 70 should_signal = false;
@@ -73,7 +73,7 @@ private:
73 rb.Push(ResultSuccess); 73 rb.Push(ResultSuccess);
74 } 74 }
75 75
76 void SetChargerTypeChangeEventEnabled(Kernel::HLERequestContext& ctx) { 76 void SetChargerTypeChangeEventEnabled(HLERequestContext& ctx) {
77 IPC::RequestParser rp{ctx}; 77 IPC::RequestParser rp{ctx};
78 const auto state = rp.Pop<bool>(); 78 const auto state = rp.Pop<bool>();
79 LOG_DEBUG(Service_PTM, "called, state={}", state); 79 LOG_DEBUG(Service_PTM, "called, state={}", state);
@@ -84,7 +84,7 @@ private:
84 rb.Push(ResultSuccess); 84 rb.Push(ResultSuccess);
85 } 85 }
86 86
87 void SetPowerSupplyChangeEventEnabled(Kernel::HLERequestContext& ctx) { 87 void SetPowerSupplyChangeEventEnabled(HLERequestContext& ctx) {
88 IPC::RequestParser rp{ctx}; 88 IPC::RequestParser rp{ctx};
89 const auto state = rp.Pop<bool>(); 89 const auto state = rp.Pop<bool>();
90 LOG_DEBUG(Service_PTM, "called, state={}", state); 90 LOG_DEBUG(Service_PTM, "called, state={}", state);
@@ -95,7 +95,7 @@ private:
95 rb.Push(ResultSuccess); 95 rb.Push(ResultSuccess);
96 } 96 }
97 97
98 void SetBatteryVoltageStateChangeEventEnabled(Kernel::HLERequestContext& ctx) { 98 void SetBatteryVoltageStateChangeEventEnabled(HLERequestContext& ctx) {
99 IPC::RequestParser rp{ctx}; 99 IPC::RequestParser rp{ctx};
100 const auto state = rp.Pop<bool>(); 100 const auto state = rp.Pop<bool>();
101 LOG_DEBUG(Service_PTM, "called, state={}", state); 101 LOG_DEBUG(Service_PTM, "called, state={}", state);
@@ -145,7 +145,7 @@ PSM::PSM(Core::System& system_) : ServiceFramework{system_, "psm"} {
145 145
146PSM::~PSM() = default; 146PSM::~PSM() = default;
147 147
148void PSM::GetBatteryChargePercentage(Kernel::HLERequestContext& ctx) { 148void PSM::GetBatteryChargePercentage(HLERequestContext& ctx) {
149 LOG_DEBUG(Service_PTM, "called"); 149 LOG_DEBUG(Service_PTM, "called");
150 150
151 IPC::ResponseBuilder rb{ctx, 3}; 151 IPC::ResponseBuilder rb{ctx, 3};
@@ -153,7 +153,7 @@ void PSM::GetBatteryChargePercentage(Kernel::HLERequestContext& ctx) {
153 rb.Push<u32>(battery_charge_percentage); 153 rb.Push<u32>(battery_charge_percentage);
154} 154}
155 155
156void PSM::GetChargerType(Kernel::HLERequestContext& ctx) { 156void PSM::GetChargerType(HLERequestContext& ctx) {
157 LOG_DEBUG(Service_PTM, "called"); 157 LOG_DEBUG(Service_PTM, "called");
158 158
159 IPC::ResponseBuilder rb{ctx, 3}; 159 IPC::ResponseBuilder rb{ctx, 3};
@@ -161,7 +161,7 @@ void PSM::GetChargerType(Kernel::HLERequestContext& ctx) {
161 rb.PushEnum(charger_type); 161 rb.PushEnum(charger_type);
162} 162}
163 163
164void PSM::OpenSession(Kernel::HLERequestContext& ctx) { 164void PSM::OpenSession(HLERequestContext& ctx) {
165 LOG_DEBUG(Service_PTM, "called"); 165 LOG_DEBUG(Service_PTM, "called");
166 166
167 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 167 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
diff --git a/src/core/hle/service/ptm/psm.h b/src/core/hle/service/ptm/psm.h
index f674ba8bc..fa47919e5 100644
--- a/src/core/hle/service/ptm/psm.h
+++ b/src/core/hle/service/ptm/psm.h
@@ -20,9 +20,9 @@ private:
20 Unknown = 3, 20 Unknown = 3,
21 }; 21 };
22 22
23 void GetBatteryChargePercentage(Kernel::HLERequestContext& ctx); 23 void GetBatteryChargePercentage(HLERequestContext& ctx);
24 void GetChargerType(Kernel::HLERequestContext& ctx); 24 void GetChargerType(HLERequestContext& ctx);
25 void OpenSession(Kernel::HLERequestContext& ctx); 25 void OpenSession(HLERequestContext& ctx);
26 26
27 u32 battery_charge_percentage{100}; 27 u32 battery_charge_percentage{100};
28 ChargerType charger_type{ChargerType::RegularCharger}; 28 ChargerType charger_type{ChargerType::RegularCharger};
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp
index 4bea995c6..6f0cfe04b 100644
--- a/src/core/hle/service/ptm/ptm.cpp
+++ b/src/core/hle/service/ptm/ptm.cpp
@@ -7,12 +7,16 @@
7#include "core/hle/service/ptm/psm.h" 7#include "core/hle/service/ptm/psm.h"
8#include "core/hle/service/ptm/ptm.h" 8#include "core/hle/service/ptm/ptm.h"
9#include "core/hle/service/ptm/ts.h" 9#include "core/hle/service/ptm/ts.h"
10#include "core/hle/service/server_manager.h"
10 11
11namespace Service::PTM { 12namespace Service::PTM {
12 13
13void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 14void LoopProcess(Core::System& system) {
14 std::make_shared<PSM>(system)->InstallAsService(sm); 15 auto server_manager = std::make_unique<ServerManager>(system);
15 std::make_shared<TS>(system)->InstallAsService(sm); 16
17 server_manager->RegisterNamedService("psm", std::make_shared<PSM>(system));
18 server_manager->RegisterNamedService("ts", std::make_shared<TS>(system));
19 ServerManager::RunServer(std::move(server_manager));
16} 20}
17 21
18} // namespace Service::PTM 22} // namespace Service::PTM
diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h
index 06224a24e..a0ae03d28 100644
--- a/src/core/hle/service/ptm/ptm.h
+++ b/src/core/hle/service/ptm/ptm.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::PTM { 10namespace Service::PTM {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::PTM 14} // namespace Service::PTM
diff --git a/src/core/hle/service/ptm/ts.cpp b/src/core/hle/service/ptm/ts.cpp
index b1a0a5544..ca064dd90 100644
--- a/src/core/hle/service/ptm/ts.cpp
+++ b/src/core/hle/service/ptm/ts.cpp
@@ -4,7 +4,7 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/core.h" 6#include "core/core.h"
7#include "core/hle/ipc_helpers.h" 7#include "core/hle/service/ipc_helpers.h"
8#include "core/hle/service/ptm/ts.h" 8#include "core/hle/service/ptm/ts.h"
9 9
10namespace Service::PTM { 10namespace Service::PTM {
@@ -25,7 +25,7 @@ TS::TS(Core::System& system_) : ServiceFramework{system_, "ts"} {
25 25
26TS::~TS() = default; 26TS::~TS() = default;
27 27
28void TS::GetTemperature(Kernel::HLERequestContext& ctx) { 28void TS::GetTemperature(HLERequestContext& ctx) {
29 IPC::RequestParser rp{ctx}; 29 IPC::RequestParser rp{ctx};
30 const auto location{rp.PopEnum<Location>()}; 30 const auto location{rp.PopEnum<Location>()};
31 31
@@ -36,7 +36,7 @@ void TS::GetTemperature(Kernel::HLERequestContext& ctx) {
36 rb.Push(temperature); 36 rb.Push(temperature);
37} 37}
38 38
39void TS::GetTemperatureMilliC(Kernel::HLERequestContext& ctx) { 39void TS::GetTemperatureMilliC(HLERequestContext& ctx) {
40 IPC::RequestParser rp{ctx}; 40 IPC::RequestParser rp{ctx};
41 const auto location{rp.PopEnum<Location>()}; 41 const auto location{rp.PopEnum<Location>()};
42 42
diff --git a/src/core/hle/service/ptm/ts.h b/src/core/hle/service/ptm/ts.h
index 39d51847e..c3f43d5a3 100644
--- a/src/core/hle/service/ptm/ts.h
+++ b/src/core/hle/service/ptm/ts.h
@@ -19,8 +19,8 @@ private:
19 External, 19 External,
20 }; 20 };
21 21
22 void GetTemperature(Kernel::HLERequestContext& ctx); 22 void GetTemperature(HLERequestContext& ctx);
23 void GetTemperatureMilliC(Kernel::HLERequestContext& ctx); 23 void GetTemperatureMilliC(HLERequestContext& ctx);
24}; 24};
25 25
26} // namespace Service::PTM 26} // namespace Service::PTM
diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp
new file mode 100644
index 000000000..bd04cd023
--- /dev/null
+++ b/src/core/hle/service/server_manager.cpp
@@ -0,0 +1,448 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/scope_exit.h"
5
6#include "core/core.h"
7#include "core/hle/kernel/k_client_port.h"
8#include "core/hle/kernel/k_client_session.h"
9#include "core/hle/kernel/k_event.h"
10#include "core/hle/kernel/k_object_name.h"
11#include "core/hle/kernel/k_port.h"
12#include "core/hle/kernel/k_server_port.h"
13#include "core/hle/kernel/k_server_session.h"
14#include "core/hle/kernel/k_synchronization_object.h"
15#include "core/hle/kernel/svc_results.h"
16#include "core/hle/service/hle_ipc.h"
17#include "core/hle/service/ipc_helpers.h"
18#include "core/hle/service/server_manager.h"
19#include "core/hle/service/sm/sm.h"
20
21namespace Service {
22
23constexpr size_t MaximumWaitObjects = 0x40;
24
25enum HandleType {
26 Port,
27 Session,
28 DeferEvent,
29 Event,
30};
31
32ServerManager::ServerManager(Core::System& system) : m_system{system}, m_serve_mutex{system} {
33 // Initialize event.
34 m_event = Kernel::KEvent::Create(system.Kernel());
35 m_event->Initialize(nullptr);
36}
37
38ServerManager::~ServerManager() {
39 // Signal stop.
40 m_stop_source.request_stop();
41 m_event->Signal();
42
43 // Wait for processing to stop.
44 m_stopped.wait(false);
45 m_threads.clear();
46
47 // Clean up ports.
48 for (const auto& [port, handler] : m_ports) {
49 port->Close();
50 }
51
52 // Clean up sessions.
53 for (const auto& [session, manager] : m_sessions) {
54 session->Close();
55 }
56
57 for (const auto& request : m_deferrals) {
58 request.session->Close();
59 }
60
61 // Close event.
62 m_event->GetReadableEvent().Close();
63 m_event->Close();
64
65 if (m_deferral_event) {
66 m_deferral_event->GetReadableEvent().Close();
67 // Write event is owned by ServiceManager
68 }
69}
70
71void ServerManager::RunServer(std::unique_ptr<ServerManager>&& server_manager) {
72 server_manager->m_system.RunServer(std::move(server_manager));
73}
74
75Result ServerManager::RegisterSession(Kernel::KServerSession* session,
76 std::shared_ptr<SessionRequestManager> manager) {
77 ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
78
79 // We are taking ownership of the server session, so don't open it.
80 // Begin tracking the server session.
81 {
82 std::scoped_lock ll{m_list_mutex};
83 m_sessions.emplace(session, std::move(manager));
84 }
85
86 // Signal the wakeup event.
87 m_event->Signal();
88
89 R_SUCCEED();
90}
91
92Result ServerManager::RegisterNamedService(const std::string& service_name,
93 std::shared_ptr<SessionRequestHandler>&& handler,
94 u32 max_sessions) {
95 ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
96
97 // Add the new server to sm:.
98 ASSERT(R_SUCCEEDED(
99 m_system.ServiceManager().RegisterService(service_name, max_sessions, handler)));
100
101 // Get the registered port.
102 auto port = m_system.ServiceManager().GetServicePort(service_name);
103 ASSERT(port.Succeeded());
104
105 // Open a new reference to the server port.
106 (*port)->GetServerPort().Open();
107
108 // Begin tracking the server port.
109 {
110 std::scoped_lock ll{m_list_mutex};
111 m_ports.emplace(std::addressof((*port)->GetServerPort()), std::move(handler));
112 }
113
114 // Signal the wakeup event.
115 m_event->Signal();
116
117 R_SUCCEED();
118}
119
120Result ServerManager::ManageNamedPort(const std::string& service_name,
121 std::shared_ptr<SessionRequestHandler>&& handler,
122 u32 max_sessions) {
123 ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
124
125 // Create a new port.
126 auto* port = Kernel::KPort::Create(m_system.Kernel());
127 port->Initialize(max_sessions, false, service_name);
128
129 // Register the port.
130 Kernel::KPort::Register(m_system.Kernel(), port);
131
132 // Ensure that our reference to the port is closed if we fail to register it.
133 SCOPE_EXIT({
134 port->GetClientPort().Close();
135 port->GetServerPort().Close();
136 });
137
138 // Register the object name with the kernel.
139 R_TRY(Kernel::KObjectName::NewFromName(m_system.Kernel(), std::addressof(port->GetClientPort()),
140 service_name.c_str()));
141
142 // Open a new reference to the server port.
143 port->GetServerPort().Open();
144
145 // Begin tracking the server port.
146 {
147 std::scoped_lock ll{m_list_mutex};
148 m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler));
149 }
150
151 // We succeeded.
152 R_SUCCEED();
153}
154
155Result ServerManager::ManageDeferral(Kernel::KEvent** out_event) {
156 // Create a new event.
157 m_deferral_event = Kernel::KEvent::Create(m_system.Kernel());
158 ASSERT(m_deferral_event != nullptr);
159
160 // Initialize the event.
161 m_deferral_event->Initialize(nullptr);
162
163 // Set the output.
164 *out_event = m_deferral_event;
165
166 // We succeeded.
167 R_SUCCEED();
168}
169
170void ServerManager::StartAdditionalHostThreads(const char* name, size_t num_threads) {
171 for (size_t i = 0; i < num_threads; i++) {
172 auto thread_name = fmt::format("{}:{}", name, i + 1);
173 m_threads.emplace_back(m_system.Kernel().RunOnHostCoreThread(
174 std::move(thread_name), [&] { this->LoopProcessImpl(); }));
175 }
176}
177
178Result ServerManager::LoopProcess() {
179 SCOPE_EXIT({
180 m_stopped.store(true);
181 m_stopped.notify_all();
182 });
183
184 R_RETURN(this->LoopProcessImpl());
185}
186
187Result ServerManager::LoopProcessImpl() {
188 while (!m_stop_source.stop_requested()) {
189 R_TRY(this->WaitAndProcessImpl());
190 }
191
192 R_SUCCEED();
193}
194
195Result ServerManager::WaitAndProcessImpl() {
196 Kernel::KScopedAutoObject<Kernel::KSynchronizationObject> wait_obj;
197 HandleType wait_type{};
198
199 // Ensure we are the only thread waiting for this server.
200 std::unique_lock sl{m_serve_mutex};
201
202 // If we're done, return before we start waiting.
203 R_SUCCEED_IF(m_stop_source.stop_requested());
204
205 // Wait for a tracked object to become signaled.
206 {
207 s32 num_objs{};
208 std::array<HandleType, MaximumWaitObjects> wait_types{};
209 std::array<Kernel::KSynchronizationObject*, MaximumWaitObjects> wait_objs{};
210
211 const auto AddWaiter{
212 [&](Kernel::KSynchronizationObject* synchronization_object, HandleType type) {
213 // Open a new reference to the object.
214 synchronization_object->Open();
215
216 // Insert into the list.
217 wait_types[num_objs] = type;
218 wait_objs[num_objs++] = synchronization_object;
219 }};
220
221 {
222 std::scoped_lock ll{m_list_mutex};
223
224 // Add all of our ports.
225 for (const auto& [port, handler] : m_ports) {
226 AddWaiter(port, HandleType::Port);
227 }
228
229 // Add all of our sessions.
230 for (const auto& [session, manager] : m_sessions) {
231 AddWaiter(session, HandleType::Session);
232 }
233 }
234
235 // Add the deferral wakeup event.
236 if (m_deferral_event != nullptr) {
237 AddWaiter(std::addressof(m_deferral_event->GetReadableEvent()), HandleType::DeferEvent);
238 }
239
240 // Add the wakeup event.
241 AddWaiter(std::addressof(m_event->GetReadableEvent()), HandleType::Event);
242
243 // Clean up extra references on exit.
244 SCOPE_EXIT({
245 for (s32 i = 0; i < num_objs; i++) {
246 wait_objs[i]->Close();
247 }
248 });
249
250 // Wait for a signal.
251 s32 out_index{-1};
252 R_TRY(Kernel::KSynchronizationObject::Wait(m_system.Kernel(), &out_index, wait_objs.data(),
253 num_objs, -1));
254 ASSERT(out_index >= 0 && out_index < num_objs);
255
256 // Set the output index.
257 wait_obj = wait_objs[out_index];
258 wait_type = wait_types[out_index];
259 }
260
261 // Process what we just received, temporarily removing the object so it is
262 // not processed concurrently by another thread.
263 {
264 switch (wait_type) {
265 case HandleType::Port: {
266 // Port signaled.
267 auto* port = wait_obj->DynamicCast<Kernel::KServerPort*>();
268 std::shared_ptr<SessionRequestHandler> handler;
269
270 // Remove from tracking.
271 {
272 std::scoped_lock ll{m_list_mutex};
273 ASSERT(m_ports.contains(port));
274 m_ports.at(port).swap(handler);
275 m_ports.erase(port);
276 }
277
278 // Allow other threads to serve.
279 sl.unlock();
280
281 // Finish.
282 R_RETURN(this->OnPortEvent(port, std::move(handler)));
283 }
284 case HandleType::Session: {
285 // Session signaled.
286 auto* session = wait_obj->DynamicCast<Kernel::KServerSession*>();
287 std::shared_ptr<SessionRequestManager> manager;
288
289 // Remove from tracking.
290 {
291 std::scoped_lock ll{m_list_mutex};
292 ASSERT(m_sessions.contains(session));
293 m_sessions.at(session).swap(manager);
294 m_sessions.erase(session);
295 }
296
297 // Allow other threads to serve.
298 sl.unlock();
299
300 // Finish.
301 R_RETURN(this->OnSessionEvent(session, std::move(manager)));
302 }
303 case HandleType::DeferEvent: {
304 // Clear event.
305 ASSERT(R_SUCCEEDED(m_deferral_event->Clear()));
306
307 // Drain the list of deferrals while we process.
308 std::list<RequestState> deferrals;
309 {
310 std::scoped_lock ll{m_list_mutex};
311 m_deferrals.swap(deferrals);
312 }
313
314 // Allow other threads to serve.
315 sl.unlock();
316
317 // Finish.
318 R_RETURN(this->OnDeferralEvent(std::move(deferrals)));
319 }
320 case HandleType::Event: {
321 // Clear event and finish.
322 R_RETURN(m_event->Clear());
323 }
324 default: {
325 UNREACHABLE();
326 }
327 }
328 }
329}
330
331Result ServerManager::OnPortEvent(Kernel::KServerPort* port,
332 std::shared_ptr<SessionRequestHandler>&& handler) {
333 // Accept a new server session.
334 Kernel::KServerSession* session = port->AcceptSession();
335 ASSERT(session != nullptr);
336
337 // Create the session manager and install the handler.
338 auto manager = std::make_shared<SessionRequestManager>(m_system.Kernel(), *this);
339 manager->SetSessionHandler(std::shared_ptr(handler));
340
341 // Track the server session.
342 {
343 std::scoped_lock ll{m_list_mutex};
344 m_ports.emplace(port, std::move(handler));
345 m_sessions.emplace(session, std::move(manager));
346 }
347
348 // Signal the wakeup event.
349 m_event->Signal();
350
351 // We succeeded.
352 R_SUCCEED();
353}
354
355Result ServerManager::OnSessionEvent(Kernel::KServerSession* session,
356 std::shared_ptr<SessionRequestManager>&& manager) {
357 Result rc{ResultSuccess};
358
359 // Try to receive a message.
360 std::shared_ptr<HLERequestContext> context;
361 rc = session->ReceiveRequest(&context, manager);
362
363 // If the session has been closed, we're done.
364 if (rc == Kernel::ResultSessionClosed) {
365 // Close the session.
366 session->Close();
367
368 // Finish.
369 R_SUCCEED();
370 }
371 ASSERT(R_SUCCEEDED(rc));
372
373 RequestState request{
374 .session = session,
375 .context = std::move(context),
376 .manager = std::move(manager),
377 };
378
379 // Complete the sync request with deferral handling.
380 R_RETURN(this->CompleteSyncRequest(std::move(request)));
381}
382
383Result ServerManager::CompleteSyncRequest(RequestState&& request) {
384 Result rc{ResultSuccess};
385 Result service_rc{ResultSuccess};
386
387 // Mark the request as not deferred.
388 request.context->SetIsDeferred(false);
389
390 // Complete the request. We have exclusive access to this session.
391 service_rc = request.manager->CompleteSyncRequest(request.session, *request.context);
392
393 // If we've been deferred, we're done.
394 if (request.context->GetIsDeferred()) {
395 // Insert into deferral list.
396 std::scoped_lock ll{m_list_mutex};
397 m_deferrals.emplace_back(std::move(request));
398
399 // Finish.
400 R_SUCCEED();
401 }
402
403 // Send the reply.
404 rc = request.session->SendReplyHLE();
405
406 // If the session has been closed, we're done.
407 if (rc == Kernel::ResultSessionClosed || service_rc == IPC::ResultSessionClosed) {
408 // Close the session.
409 request.session->Close();
410
411 // Finish.
412 R_SUCCEED();
413 }
414
415 ASSERT(R_SUCCEEDED(rc));
416 ASSERT(R_SUCCEEDED(service_rc));
417
418 // Reinsert the session.
419 {
420 std::scoped_lock ll{m_list_mutex};
421 m_sessions.emplace(request.session, std::move(request.manager));
422 }
423
424 // Signal the wakeup event.
425 m_event->Signal();
426
427 // We succeeded.
428 R_SUCCEED();
429}
430
431Result ServerManager::OnDeferralEvent(std::list<RequestState>&& deferrals) {
432 ON_RESULT_FAILURE {
433 std::scoped_lock ll{m_list_mutex};
434 m_deferrals.splice(m_deferrals.end(), deferrals);
435 };
436
437 while (!deferrals.empty()) {
438 RequestState request = deferrals.front();
439 deferrals.pop_front();
440
441 // Try again to complete the request.
442 R_TRY(this->CompleteSyncRequest(std::move(request)));
443 }
444
445 R_SUCCEED();
446}
447
448} // namespace Service
diff --git a/src/core/hle/service/server_manager.h b/src/core/hle/service/server_manager.h
new file mode 100644
index 000000000..fdb8af2ff
--- /dev/null
+++ b/src/core/hle/service/server_manager.h
@@ -0,0 +1,90 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <atomic>
7#include <functional>
8#include <list>
9#include <map>
10#include <mutex>
11#include <string_view>
12#include <vector>
13
14#include "common/polyfill_thread.h"
15#include "core/hle/result.h"
16#include "core/hle/service/mutex.h"
17
18namespace Core {
19class System;
20}
21
22namespace Kernel {
23class KEvent;
24class KServerPort;
25class KServerSession;
26class KSynchronizationObject;
27} // namespace Kernel
28
29namespace Service {
30
31class HLERequestContext;
32class SessionRequestHandler;
33class SessionRequestManager;
34
35class ServerManager {
36public:
37 explicit ServerManager(Core::System& system);
38 ~ServerManager();
39
40 Result RegisterSession(Kernel::KServerSession* session,
41 std::shared_ptr<SessionRequestManager> manager);
42 Result RegisterNamedService(const std::string& service_name,
43 std::shared_ptr<SessionRequestHandler>&& handler,
44 u32 max_sessions = 64);
45 Result ManageNamedPort(const std::string& service_name,
46 std::shared_ptr<SessionRequestHandler>&& handler, u32 max_sessions = 64);
47 Result ManageDeferral(Kernel::KEvent** out_event);
48
49 Result LoopProcess();
50 void StartAdditionalHostThreads(const char* name, size_t num_threads);
51
52 static void RunServer(std::unique_ptr<ServerManager>&& server);
53
54private:
55 struct RequestState;
56
57 Result LoopProcessImpl();
58 Result WaitAndProcessImpl();
59 Result OnPortEvent(Kernel::KServerPort* port, std::shared_ptr<SessionRequestHandler>&& handler);
60 Result OnSessionEvent(Kernel::KServerSession* session,
61 std::shared_ptr<SessionRequestManager>&& manager);
62 Result OnDeferralEvent(std::list<RequestState>&& deferrals);
63 Result CompleteSyncRequest(RequestState&& state);
64
65private:
66 Core::System& m_system;
67 Mutex m_serve_mutex;
68 std::mutex m_list_mutex;
69
70 // Guest state tracking
71 std::map<Kernel::KServerPort*, std::shared_ptr<SessionRequestHandler>> m_ports{};
72 std::map<Kernel::KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions{};
73 Kernel::KEvent* m_event{};
74 Kernel::KEvent* m_deferral_event{};
75
76 // Deferral tracking
77 struct RequestState {
78 Kernel::KServerSession* session;
79 std::shared_ptr<HLERequestContext> context;
80 std::shared_ptr<SessionRequestManager> manager;
81 };
82 std::list<RequestState> m_deferrals{};
83
84 // Host state tracking
85 std::atomic<bool> m_stopped{};
86 std::vector<std::jthread> m_threads{};
87 std::stop_source m_stop_source{};
88};
89
90} // namespace Service
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 1ffc1c694..69cdb5918 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -7,7 +7,6 @@
7#include "common/settings.h" 7#include "common/settings.h"
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/ipc.h" 9#include "core/hle/ipc.h"
10#include "core/hle/ipc_helpers.h"
11#include "core/hle/kernel/k_process.h" 10#include "core/hle/kernel/k_process.h"
12#include "core/hle/kernel/k_server_port.h" 11#include "core/hle/kernel/k_server_port.h"
13#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/kernel.h"
@@ -31,6 +30,7 @@
31#include "core/hle/service/glue/glue.h" 30#include "core/hle/service/glue/glue.h"
32#include "core/hle/service/grc/grc.h" 31#include "core/hle/service/grc/grc.h"
33#include "core/hle/service/hid/hid.h" 32#include "core/hle/service/hid/hid.h"
33#include "core/hle/service/ipc_helpers.h"
34#include "core/hle/service/jit/jit.h" 34#include "core/hle/service/jit/jit.h"
35#include "core/hle/service/lbl/lbl.h" 35#include "core/hle/service/lbl/lbl.h"
36#include "core/hle/service/ldn/ldn.h" 36#include "core/hle/service/ldn/ldn.h"
@@ -49,8 +49,8 @@
49#include "core/hle/service/npns/npns.h" 49#include "core/hle/service/npns/npns.h"
50#include "core/hle/service/ns/ns.h" 50#include "core/hle/service/ns/ns.h"
51#include "core/hle/service/nvdrv/nvdrv.h" 51#include "core/hle/service/nvdrv/nvdrv.h"
52#include "core/hle/service/nvflinger/hos_binder_driver_server.h" 52#include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
53#include "core/hle/service/nvflinger/nvflinger.h" 53#include "core/hle/service/nvnflinger/nvnflinger.h"
54#include "core/hle/service/olsc/olsc.h" 54#include "core/hle/service/olsc/olsc.h"
55#include "core/hle/service/pcie/pcie.h" 55#include "core/hle/service/pcie/pcie.h"
56#include "core/hle/service/pctl/pctl_module.h" 56#include "core/hle/service/pctl/pctl_module.h"
@@ -90,44 +90,13 @@ namespace Service {
90} 90}
91 91
92ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_, 92ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_,
93 ServiceThreadType thread_type, u32 max_sessions_, 93 u32 max_sessions_, InvokerFn* handler_invoker_)
94 InvokerFn* handler_invoker_) 94 : SessionRequestHandler(system_.Kernel(), service_name_), system{system_},
95 : SessionRequestHandler(system_.Kernel(), service_name_, thread_type), system{system_},
96 service_name{service_name_}, max_sessions{max_sessions_}, handler_invoker{handler_invoker_} {} 95 service_name{service_name_}, max_sessions{max_sessions_}, handler_invoker{handler_invoker_} {}
97 96
98ServiceFrameworkBase::~ServiceFrameworkBase() { 97ServiceFrameworkBase::~ServiceFrameworkBase() {
99 // Wait for other threads to release access before destroying 98 // Wait for other threads to release access before destroying
100 const auto guard = LockService(); 99 const auto guard = LockService();
101
102 if (named_port != nullptr) {
103 named_port->GetClientPort().Close();
104 named_port->GetServerPort().Close();
105 named_port = nullptr;
106 }
107}
108
109void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) {
110 const auto guard = LockService();
111
112 ASSERT(!service_registered);
113
114 service_manager.RegisterService(service_name, max_sessions, shared_from_this());
115 service_registered = true;
116}
117
118Kernel::KClientPort& ServiceFrameworkBase::CreatePort() {
119 const auto guard = LockService();
120
121 if (named_port == nullptr) {
122 ASSERT(!service_registered);
123
124 named_port = Kernel::KPort::Create(kernel);
125 named_port->Initialize(max_sessions, false, service_name);
126
127 service_registered = true;
128 }
129
130 return named_port->GetClientPort();
131} 100}
132 101
133void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) { 102void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) {
@@ -148,7 +117,7 @@ void ServiceFrameworkBase::RegisterHandlersBaseTipc(const FunctionInfoBase* func
148 } 117 }
149} 118}
150 119
151void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, 120void ServiceFrameworkBase::ReportUnimplementedFunction(HLERequestContext& ctx,
152 const FunctionInfoBase* info) { 121 const FunctionInfoBase* info) {
153 auto cmd_buf = ctx.CommandBuffer(); 122 auto cmd_buf = ctx.CommandBuffer();
154 std::string function_name = info == nullptr ? fmt::format("{}", ctx.GetCommand()) : info->name; 123 std::string function_name = info == nullptr ? fmt::format("{}", ctx.GetCommand()) : info->name;
@@ -171,7 +140,7 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext
171 } 140 }
172} 141}
173 142
174void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) { 143void ServiceFrameworkBase::InvokeRequest(HLERequestContext& ctx) {
175 auto itr = handlers.find(ctx.GetCommand()); 144 auto itr = handlers.find(ctx.GetCommand());
176 const FunctionInfoBase* info = itr == handlers.end() ? nullptr : &itr->second; 145 const FunctionInfoBase* info = itr == handlers.end() ? nullptr : &itr->second;
177 if (info == nullptr || info->handler_callback == nullptr) { 146 if (info == nullptr || info->handler_callback == nullptr) {
@@ -182,7 +151,7 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) {
182 handler_invoker(this, info->handler_callback, ctx); 151 handler_invoker(this, info->handler_callback, ctx);
183} 152}
184 153
185void ServiceFrameworkBase::InvokeRequestTipc(Kernel::HLERequestContext& ctx) { 154void ServiceFrameworkBase::InvokeRequestTipc(HLERequestContext& ctx) {
186 boost::container::flat_map<u32, FunctionInfoBase>::iterator itr; 155 boost::container::flat_map<u32, FunctionInfoBase>::iterator itr;
187 156
188 itr = handlers_tipc.find(ctx.GetCommand()); 157 itr = handlers_tipc.find(ctx.GetCommand());
@@ -197,7 +166,7 @@ void ServiceFrameworkBase::InvokeRequestTipc(Kernel::HLERequestContext& ctx) {
197} 166}
198 167
199Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session, 168Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session,
200 Kernel::HLERequestContext& ctx) { 169 HLERequestContext& ctx) {
201 const auto guard = LockService(); 170 const auto guard = LockService();
202 171
203 Result result = ResultSuccess; 172 Result result = ResultSuccess;
@@ -207,7 +176,7 @@ Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session,
207 case IPC::CommandType::TIPC_Close: { 176 case IPC::CommandType::TIPC_Close: {
208 IPC::ResponseBuilder rb{ctx, 2}; 177 IPC::ResponseBuilder rb{ctx, 2};
209 rb.Push(ResultSuccess); 178 rb.Push(ResultSuccess);
210 result = IPC::ERR_REMOTE_PROCESS_DEAD; 179 result = IPC::ResultSessionClosed;
211 break; 180 break;
212 } 181 }
213 case IPC::CommandType::ControlWithContext: 182 case IPC::CommandType::ControlWithContext:
@@ -241,70 +210,72 @@ Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session,
241 210
242/// Initialize Services 211/// Initialize Services
243Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) 212Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system)
244 : hos_binder_driver_server{std::make_unique<NVFlinger::HosBinderDriverServer>(system)}, 213 : hos_binder_driver_server{std::make_unique<Nvnflinger::HosBinderDriverServer>(system)},
245 nv_flinger{std::make_unique<NVFlinger::NVFlinger>(system, *hos_binder_driver_server)} { 214 nv_flinger{std::make_unique<Nvnflinger::Nvnflinger>(system, *hos_binder_driver_server)} {
246 215
247 // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it 216 auto& kernel = system.Kernel();
248 // here and pass it into the respective InstallInterfaces functions.
249 217
218 // Nvnflinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
219 // here and pass it into the respective InstallInterfaces functions.
250 system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); 220 system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false);
251 221
252 system.Kernel().RegisterNamedService("sm:", SM::ServiceManager::InterfaceFactory); 222 // clang-format off
253 system.Kernel().RegisterInterfaceForNamedService("sm:", SM::ServiceManager::SessionHandler); 223 kernel.RunOnHostCoreProcess("audio", [&] { Audio::LoopProcess(system); }).detach();
254 224 kernel.RunOnHostCoreProcess("FS", [&] { FileSystem::LoopProcess(system); }).detach();
255 Account::InstallInterfaces(system); 225 kernel.RunOnHostCoreProcess("jit", [&] { JIT::LoopProcess(system); }).detach();
256 AM::InstallInterfaces(*sm, *nv_flinger, system); 226 kernel.RunOnHostCoreProcess("ldn", [&] { LDN::LoopProcess(system); }).detach();
257 AOC::InstallInterfaces(*sm, system); 227 kernel.RunOnHostCoreProcess("Loader", [&] { LDR::LoopProcess(system); }).detach();
258 APM::InstallInterfaces(system); 228 kernel.RunOnHostCoreProcess("nvservices", [&] { Nvidia::LoopProcess(*nv_flinger, system); }).detach();
259 Audio::InstallInterfaces(*sm, system); 229 kernel.RunOnHostCoreProcess("bsdsocket", [&] { Sockets::LoopProcess(system); }).detach();
260 BCAT::InstallInterfaces(system); 230 kernel.RunOnHostCoreProcess("vi", [&] { VI::LoopProcess(system, *nv_flinger, *hos_binder_driver_server); }).detach();
261 BPC::InstallInterfaces(*sm, system); 231
262 BtDrv::InstallInterfaces(*sm, system); 232 kernel.RunOnGuestCoreProcess("sm", [&] { SM::LoopProcess(system); });
263 BTM::InstallInterfaces(*sm, system); 233 kernel.RunOnGuestCoreProcess("account", [&] { Account::LoopProcess(system); });
264 Capture::InstallInterfaces(*sm, system); 234 kernel.RunOnGuestCoreProcess("am", [&] { AM::LoopProcess(*nv_flinger, system); });
265 ERPT::InstallInterfaces(*sm, system); 235 kernel.RunOnGuestCoreProcess("aoc", [&] { AOC::LoopProcess(system); });
266 ES::InstallInterfaces(*sm, system); 236 kernel.RunOnGuestCoreProcess("apm", [&] { APM::LoopProcess(system); });
267 EUPLD::InstallInterfaces(*sm, system); 237 kernel.RunOnGuestCoreProcess("bcat", [&] { BCAT::LoopProcess(system); });
268 Fatal::InstallInterfaces(*sm, system); 238 kernel.RunOnGuestCoreProcess("bpc", [&] { BPC::LoopProcess(system); });
269 FGM::InstallInterfaces(*sm, system); 239 kernel.RunOnGuestCoreProcess("btdrv", [&] { BtDrv::LoopProcess(system); });
270 FileSystem::InstallInterfaces(system); 240 kernel.RunOnGuestCoreProcess("btm", [&] { BTM::LoopProcess(system); });
271 Friend::InstallInterfaces(*sm, system); 241 kernel.RunOnGuestCoreProcess("capsrv", [&] { Capture::LoopProcess(system); });
272 Glue::InstallInterfaces(system); 242 kernel.RunOnGuestCoreProcess("erpt", [&] { ERPT::LoopProcess(system); });
273 GRC::InstallInterfaces(*sm, system); 243 kernel.RunOnGuestCoreProcess("es", [&] { ES::LoopProcess(system); });
274 HID::InstallInterfaces(*sm, system); 244 kernel.RunOnGuestCoreProcess("eupld", [&] { EUPLD::LoopProcess(system); });
275 JIT::InstallInterfaces(*sm, system); 245 kernel.RunOnGuestCoreProcess("fatal", [&] { Fatal::LoopProcess(system); });
276 LBL::InstallInterfaces(*sm, system); 246 kernel.RunOnGuestCoreProcess("fgm", [&] { FGM::LoopProcess(system); });
277 LDN::InstallInterfaces(*sm, system); 247 kernel.RunOnGuestCoreProcess("friends", [&] { Friend::LoopProcess(system); });
278 LDR::InstallInterfaces(*sm, system); 248 kernel.RunOnGuestCoreProcess("glue", [&] { Glue::LoopProcess(system); });
279 LM::InstallInterfaces(system); 249 kernel.RunOnGuestCoreProcess("grc", [&] { GRC::LoopProcess(system); });
280 Migration::InstallInterfaces(*sm, system); 250 kernel.RunOnGuestCoreProcess("hid", [&] { HID::LoopProcess(system); });
281 Mii::InstallInterfaces(*sm, system); 251 kernel.RunOnGuestCoreProcess("lbl", [&] { LBL::LoopProcess(system); });
282 MM::InstallInterfaces(*sm, system); 252 kernel.RunOnGuestCoreProcess("LogManager.Prod", [&] { LM::LoopProcess(system); });
283 MNPP::InstallInterfaces(*sm, system); 253 kernel.RunOnGuestCoreProcess("mig", [&] { Migration::LoopProcess(system); });
284 NCM::InstallInterfaces(*sm, system); 254 kernel.RunOnGuestCoreProcess("mii", [&] { Mii::LoopProcess(system); });
285 NFC::InstallInterfaces(*sm, system); 255 kernel.RunOnGuestCoreProcess("mm", [&] { MM::LoopProcess(system); });
286 NFP::InstallInterfaces(*sm, system); 256 kernel.RunOnGuestCoreProcess("mnpp", [&] { MNPP::LoopProcess(system); });
287 NGCT::InstallInterfaces(*sm, system); 257 kernel.RunOnGuestCoreProcess("NCM", [&] { NCM::LoopProcess(system); });
288 NIFM::InstallInterfaces(*sm, system); 258 kernel.RunOnGuestCoreProcess("nfc", [&] { NFC::LoopProcess(system); });
289 NIM::InstallInterfaces(*sm, system); 259 kernel.RunOnGuestCoreProcess("nfp", [&] { NFP::LoopProcess(system); });
290 NPNS::InstallInterfaces(*sm, system); 260 kernel.RunOnGuestCoreProcess("ngct", [&] { NGCT::LoopProcess(system); });
291 NS::InstallInterfaces(*sm, system); 261 kernel.RunOnGuestCoreProcess("nifm", [&] { NIFM::LoopProcess(system); });
292 Nvidia::InstallInterfaces(*sm, *nv_flinger, system); 262 kernel.RunOnGuestCoreProcess("nim", [&] { NIM::LoopProcess(system); });
293 OLSC::InstallInterfaces(*sm, system); 263 kernel.RunOnGuestCoreProcess("npns", [&] { NPNS::LoopProcess(system); });
294 PCIe::InstallInterfaces(*sm, system); 264 kernel.RunOnGuestCoreProcess("ns", [&] { NS::LoopProcess(system); });
295 PCTL::InstallInterfaces(*sm, system); 265 kernel.RunOnGuestCoreProcess("olsc", [&] { OLSC::LoopProcess(system); });
296 PCV::InstallInterfaces(*sm, system); 266 kernel.RunOnGuestCoreProcess("pcie", [&] { PCIe::LoopProcess(system); });
297 PlayReport::InstallInterfaces(*sm, system); 267 kernel.RunOnGuestCoreProcess("pctl", [&] { PCTL::LoopProcess(system); });
298 PM::InstallInterfaces(system); 268 kernel.RunOnGuestCoreProcess("pcv", [&] { PCV::LoopProcess(system); });
299 PSC::InstallInterfaces(*sm, system); 269 kernel.RunOnGuestCoreProcess("prepo", [&] { PlayReport::LoopProcess(system); });
300 PTM::InstallInterfaces(*sm, system); 270 kernel.RunOnGuestCoreProcess("ProcessManager", [&] { PM::LoopProcess(system); });
301 Set::InstallInterfaces(*sm, system); 271 kernel.RunOnGuestCoreProcess("psc", [&] { PSC::LoopProcess(system); });
302 Sockets::InstallInterfaces(*sm, system); 272 kernel.RunOnGuestCoreProcess("ptm", [&] { PTM::LoopProcess(system); });
303 SPL::InstallInterfaces(*sm, system); 273 kernel.RunOnGuestCoreProcess("settings", [&] { Set::LoopProcess(system); });
304 SSL::InstallInterfaces(*sm, system); 274 kernel.RunOnGuestCoreProcess("spl", [&] { SPL::LoopProcess(system); });
305 Time::InstallInterfaces(system); 275 kernel.RunOnGuestCoreProcess("ssl", [&] { SSL::LoopProcess(system); });
306 USB::InstallInterfaces(*sm, system); 276 kernel.RunOnGuestCoreProcess("time", [&] { Time::LoopProcess(system); });
307 VI::InstallInterfaces(*sm, system, *nv_flinger, *hos_binder_driver_server); 277 kernel.RunOnGuestCoreProcess("usb", [&] { USB::LoopProcess(system); });
278 // clang-format on
308} 279}
309 280
310Services::~Services() = default; 281Services::~Services() = default;
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 22e2119d7..0f79a1b7e 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -8,7 +8,7 @@
8#include <string> 8#include <string>
9#include <boost/container/flat_map.hpp> 9#include <boost/container/flat_map.hpp>
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "core/hle/kernel/hle_ipc.h" 11#include "core/hle/service/hle_ipc.h"
12 12
13//////////////////////////////////////////////////////////////////////////////////////////////////// 13////////////////////////////////////////////////////////////////////////////////////////////////////
14// Namespace Service 14// Namespace Service
@@ -18,9 +18,6 @@ class System;
18} 18}
19 19
20namespace Kernel { 20namespace Kernel {
21class HLERequestContext;
22class KClientPort;
23class KPort;
24class KServerSession; 21class KServerSession;
25class ServiceThread; 22class ServiceThread;
26} // namespace Kernel 23} // namespace Kernel
@@ -31,10 +28,10 @@ namespace FileSystem {
31class FileSystemController; 28class FileSystemController;
32} 29}
33 30
34namespace NVFlinger { 31namespace Nvnflinger {
35class HosBinderDriverServer; 32class HosBinderDriverServer;
36class NVFlinger; 33class Nvnflinger;
37} // namespace NVFlinger 34} // namespace Nvnflinger
38 35
39namespace SM { 36namespace SM {
40class ServiceManager; 37class ServiceManager;
@@ -52,7 +49,7 @@ static_assert(ServerSessionCountMax == 0x40,
52 * 49 *
53 * @see ServiceFramework 50 * @see ServiceFramework
54 */ 51 */
55class ServiceFrameworkBase : public Kernel::SessionRequestHandler { 52class ServiceFrameworkBase : public SessionRequestHandler {
56public: 53public:
57 /// Returns the string identifier used to connect to the service. 54 /// Returns the string identifier used to connect to the service.
58 std::string GetServiceName() const { 55 std::string GetServiceName() const {
@@ -67,26 +64,19 @@ public:
67 return max_sessions; 64 return max_sessions;
68 } 65 }
69 66
70 /// Creates a port pair and registers this service with the given ServiceManager.
71 void InstallAsService(SM::ServiceManager& service_manager);
72
73 /// Invokes a service request routine using the HIPC protocol. 67 /// Invokes a service request routine using the HIPC protocol.
74 void InvokeRequest(Kernel::HLERequestContext& ctx); 68 void InvokeRequest(HLERequestContext& ctx);
75 69
76 /// Invokes a service request routine using the HIPC protocol. 70 /// Invokes a service request routine using the HIPC protocol.
77 void InvokeRequestTipc(Kernel::HLERequestContext& ctx); 71 void InvokeRequestTipc(HLERequestContext& ctx);
78
79 /// Creates a port pair and registers it on the kernel's global port registry.
80 Kernel::KClientPort& CreatePort();
81 72
82 /// Handles a synchronization request for the service. 73 /// Handles a synchronization request for the service.
83 Result HandleSyncRequest(Kernel::KServerSession& session, 74 Result HandleSyncRequest(Kernel::KServerSession& session, HLERequestContext& context) override;
84 Kernel::HLERequestContext& context) override;
85 75
86protected: 76protected:
87 /// Member-function pointer type of SyncRequest handlers. 77 /// Member-function pointer type of SyncRequest handlers.
88 template <typename Self> 78 template <typename Self>
89 using HandlerFnP = void (Self::*)(Kernel::HLERequestContext&); 79 using HandlerFnP = void (Self::*)(HLERequestContext&);
90 80
91 /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread. 81 /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
92 [[nodiscard]] std::scoped_lock<std::mutex> LockService() { 82 [[nodiscard]] std::scoped_lock<std::mutex> LockService() {
@@ -99,9 +89,6 @@ protected:
99 /// Identifier string used to connect to the service. 89 /// Identifier string used to connect to the service.
100 std::string service_name; 90 std::string service_name;
101 91
102 /// Port used by ManageNamedPort.
103 Kernel::KPort* named_port{};
104
105private: 92private:
106 template <typename T> 93 template <typename T>
107 friend class ServiceFramework; 94 friend class ServiceFramework;
@@ -113,16 +100,15 @@ private:
113 }; 100 };
114 101
115 using InvokerFn = void(ServiceFrameworkBase* object, HandlerFnP<ServiceFrameworkBase> member, 102 using InvokerFn = void(ServiceFrameworkBase* object, HandlerFnP<ServiceFrameworkBase> member,
116 Kernel::HLERequestContext& ctx); 103 HLERequestContext& ctx);
117 104
118 explicit ServiceFrameworkBase(Core::System& system_, const char* service_name_, 105 explicit ServiceFrameworkBase(Core::System& system_, const char* service_name_,
119 ServiceThreadType thread_type, u32 max_sessions_, 106 u32 max_sessions_, InvokerFn* handler_invoker_);
120 InvokerFn* handler_invoker_);
121 ~ServiceFrameworkBase() override; 107 ~ServiceFrameworkBase() override;
122 108
123 void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n); 109 void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n);
124 void RegisterHandlersBaseTipc(const FunctionInfoBase* functions, std::size_t n); 110 void RegisterHandlersBaseTipc(const FunctionInfoBase* functions, std::size_t n);
125 void ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, const FunctionInfoBase* info); 111 void ReportUnimplementedFunction(HLERequestContext& ctx, const FunctionInfoBase* info);
126 112
127 /// Maximum number of concurrent sessions that this service can handle. 113 /// Maximum number of concurrent sessions that this service can handle.
128 u32 max_sessions; 114 u32 max_sessions;
@@ -181,15 +167,12 @@ protected:
181 * 167 *
182 * @param system_ The system context to construct this service under. 168 * @param system_ The system context to construct this service under.
183 * @param service_name_ Name of the service. 169 * @param service_name_ Name of the service.
184 * @param thread_type Specifies the thread type for this service. If this is set to CreateNew,
185 * it creates a new thread for it, otherwise this uses the default thread.
186 * @param max_sessions_ Maximum number of sessions that can be connected to this service at the 170 * @param max_sessions_ Maximum number of sessions that can be connected to this service at the
187 * same time. 171 * same time.
188 */ 172 */
189 explicit ServiceFramework(Core::System& system_, const char* service_name_, 173 explicit ServiceFramework(Core::System& system_, const char* service_name_,
190 ServiceThreadType thread_type = ServiceThreadType::Default,
191 u32 max_sessions_ = ServerSessionCountMax) 174 u32 max_sessions_ = ServerSessionCountMax)
192 : ServiceFrameworkBase(system_, service_name_, thread_type, max_sessions_, Invoker) {} 175 : ServiceFrameworkBase(system_, service_name_, max_sessions_, Invoker) {}
193 176
194 /// Registers handlers in the service. 177 /// Registers handlers in the service.
195 template <std::size_t N> 178 template <std::size_t N>
@@ -227,7 +210,7 @@ private:
227 * of the derived class in order to invoke one of it's functions through a pointer. 210 * of the derived class in order to invoke one of it's functions through a pointer.
228 */ 211 */
229 static void Invoker(ServiceFrameworkBase* object, HandlerFnP<ServiceFrameworkBase> member, 212 static void Invoker(ServiceFrameworkBase* object, HandlerFnP<ServiceFrameworkBase> member,
230 Kernel::HLERequestContext& ctx) { 213 HLERequestContext& ctx) {
231 // Cast back up to our original types and call the member function 214 // Cast back up to our original types and call the member function
232 (static_cast<Self*>(object)->*static_cast<HandlerFnP<Self>>(member))(ctx); 215 (static_cast<Self*>(object)->*static_cast<HandlerFnP<Self>>(member))(ctx);
233 } 216 }
@@ -245,8 +228,8 @@ public:
245 void KillNVNFlinger(); 228 void KillNVNFlinger();
246 229
247private: 230private:
248 std::unique_ptr<NVFlinger::HosBinderDriverServer> hos_binder_driver_server; 231 std::unique_ptr<Nvnflinger::HosBinderDriverServer> hos_binder_driver_server;
249 std::unique_ptr<NVFlinger::NVFlinger> nv_flinger; 232 std::unique_ptr<Nvnflinger::Nvnflinger> nv_flinger;
250}; 233};
251 234
252} // namespace Service 235} // namespace Service
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index 16c5eaf75..f5788b481 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -6,7 +6,7 @@
6#include <chrono> 6#include <chrono>
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "common/settings.h" 8#include "common/settings.h"
9#include "core/hle/ipc_helpers.h" 9#include "core/hle/service/ipc_helpers.h"
10#include "core/hle/service/set/set.h" 10#include "core/hle/service/set/set.h"
11 11
12namespace Service::Set { 12namespace Service::Set {
@@ -74,15 +74,15 @@ constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> language_to_la
74constexpr std::size_t PRE_4_0_0_MAX_ENTRIES = 0xF; 74constexpr std::size_t PRE_4_0_0_MAX_ENTRIES = 0xF;
75constexpr std::size_t POST_4_0_0_MAX_ENTRIES = 0x40; 75constexpr std::size_t POST_4_0_0_MAX_ENTRIES = 0x40;
76 76
77constexpr Result ERR_INVALID_LANGUAGE{ErrorModule::Settings, 625}; 77constexpr Result ResultInvalidLanguage{ErrorModule::Settings, 625};
78 78
79void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, std::size_t num_language_codes) { 79void PushResponseLanguageCode(HLERequestContext& ctx, std::size_t num_language_codes) {
80 IPC::ResponseBuilder rb{ctx, 3}; 80 IPC::ResponseBuilder rb{ctx, 3};
81 rb.Push(ResultSuccess); 81 rb.Push(ResultSuccess);
82 rb.Push(static_cast<u32>(num_language_codes)); 82 rb.Push(static_cast<u32>(num_language_codes));
83} 83}
84 84
85void GetAvailableLanguageCodesImpl(Kernel::HLERequestContext& ctx, std::size_t max_entries) { 85void GetAvailableLanguageCodesImpl(HLERequestContext& ctx, std::size_t max_entries) {
86 const std::size_t requested_amount = ctx.GetWriteBufferNumElements<LanguageCode>(); 86 const std::size_t requested_amount = ctx.GetWriteBufferNumElements<LanguageCode>();
87 const std::size_t max_amount = std::min(requested_amount, max_entries); 87 const std::size_t max_amount = std::min(requested_amount, max_entries);
88 const std::size_t copy_amount = std::min(available_language_codes.size(), max_amount); 88 const std::size_t copy_amount = std::min(available_language_codes.size(), max_amount);
@@ -92,7 +92,7 @@ void GetAvailableLanguageCodesImpl(Kernel::HLERequestContext& ctx, std::size_t m
92 PushResponseLanguageCode(ctx, copy_amount); 92 PushResponseLanguageCode(ctx, copy_amount);
93} 93}
94 94
95void GetKeyCodeMapImpl(Kernel::HLERequestContext& ctx) { 95void GetKeyCodeMapImpl(HLERequestContext& ctx) {
96 const auto language_code = available_language_codes[Settings::values.language_index.GetValue()]; 96 const auto language_code = available_language_codes[Settings::values.language_index.GetValue()];
97 const auto key_code = 97 const auto key_code =
98 std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), 98 std::find_if(language_to_layout.cbegin(), language_to_layout.cend(),
@@ -117,20 +117,20 @@ LanguageCode GetLanguageCodeFromIndex(std::size_t index) {
117 return available_language_codes.at(index); 117 return available_language_codes.at(index);
118} 118}
119 119
120void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { 120void SET::GetAvailableLanguageCodes(HLERequestContext& ctx) {
121 LOG_DEBUG(Service_SET, "called"); 121 LOG_DEBUG(Service_SET, "called");
122 122
123 GetAvailableLanguageCodesImpl(ctx, PRE_4_0_0_MAX_ENTRIES); 123 GetAvailableLanguageCodesImpl(ctx, PRE_4_0_0_MAX_ENTRIES);
124} 124}
125 125
126void SET::MakeLanguageCode(Kernel::HLERequestContext& ctx) { 126void SET::MakeLanguageCode(HLERequestContext& ctx) {
127 IPC::RequestParser rp{ctx}; 127 IPC::RequestParser rp{ctx};
128 const auto index = rp.Pop<u32>(); 128 const auto index = rp.Pop<u32>();
129 129
130 if (index >= available_language_codes.size()) { 130 if (index >= available_language_codes.size()) {
131 LOG_ERROR(Service_SET, "Invalid language code index! index={}", index); 131 LOG_ERROR(Service_SET, "Invalid language code index! index={}", index);
132 IPC::ResponseBuilder rb{ctx, 2}; 132 IPC::ResponseBuilder rb{ctx, 2};
133 rb.Push(ERR_INVALID_LANGUAGE); 133 rb.Push(Set::ResultInvalidLanguage);
134 return; 134 return;
135 } 135 }
136 136
@@ -139,25 +139,25 @@ void SET::MakeLanguageCode(Kernel::HLERequestContext& ctx) {
139 rb.PushEnum(available_language_codes[index]); 139 rb.PushEnum(available_language_codes[index]);
140} 140}
141 141
142void SET::GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx) { 142void SET::GetAvailableLanguageCodes2(HLERequestContext& ctx) {
143 LOG_DEBUG(Service_SET, "called"); 143 LOG_DEBUG(Service_SET, "called");
144 144
145 GetAvailableLanguageCodesImpl(ctx, POST_4_0_0_MAX_ENTRIES); 145 GetAvailableLanguageCodesImpl(ctx, POST_4_0_0_MAX_ENTRIES);
146} 146}
147 147
148void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) { 148void SET::GetAvailableLanguageCodeCount(HLERequestContext& ctx) {
149 LOG_DEBUG(Service_SET, "called"); 149 LOG_DEBUG(Service_SET, "called");
150 150
151 PushResponseLanguageCode(ctx, PRE_4_0_0_MAX_ENTRIES); 151 PushResponseLanguageCode(ctx, PRE_4_0_0_MAX_ENTRIES);
152} 152}
153 153
154void SET::GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx) { 154void SET::GetAvailableLanguageCodeCount2(HLERequestContext& ctx) {
155 LOG_DEBUG(Service_SET, "called"); 155 LOG_DEBUG(Service_SET, "called");
156 156
157 PushResponseLanguageCode(ctx, POST_4_0_0_MAX_ENTRIES); 157 PushResponseLanguageCode(ctx, POST_4_0_0_MAX_ENTRIES);
158} 158}
159 159
160void SET::GetQuestFlag(Kernel::HLERequestContext& ctx) { 160void SET::GetQuestFlag(HLERequestContext& ctx) {
161 LOG_DEBUG(Service_SET, "called"); 161 LOG_DEBUG(Service_SET, "called");
162 162
163 IPC::ResponseBuilder rb{ctx, 3}; 163 IPC::ResponseBuilder rb{ctx, 3};
@@ -165,7 +165,7 @@ void SET::GetQuestFlag(Kernel::HLERequestContext& ctx) {
165 rb.Push(static_cast<u32>(Settings::values.quest_flag.GetValue())); 165 rb.Push(static_cast<u32>(Settings::values.quest_flag.GetValue()));
166} 166}
167 167
168void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { 168void SET::GetLanguageCode(HLERequestContext& ctx) {
169 LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index.GetValue()); 169 LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index.GetValue());
170 170
171 IPC::ResponseBuilder rb{ctx, 4}; 171 IPC::ResponseBuilder rb{ctx, 4};
@@ -173,7 +173,7 @@ void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) {
173 rb.PushEnum(available_language_codes[Settings::values.language_index.GetValue()]); 173 rb.PushEnum(available_language_codes[Settings::values.language_index.GetValue()]);
174} 174}
175 175
176void SET::GetRegionCode(Kernel::HLERequestContext& ctx) { 176void SET::GetRegionCode(HLERequestContext& ctx) {
177 LOG_DEBUG(Service_SET, "called"); 177 LOG_DEBUG(Service_SET, "called");
178 178
179 IPC::ResponseBuilder rb{ctx, 3}; 179 IPC::ResponseBuilder rb{ctx, 3};
@@ -181,17 +181,17 @@ void SET::GetRegionCode(Kernel::HLERequestContext& ctx) {
181 rb.Push(Settings::values.region_index.GetValue()); 181 rb.Push(Settings::values.region_index.GetValue());
182} 182}
183 183
184void SET::GetKeyCodeMap(Kernel::HLERequestContext& ctx) { 184void SET::GetKeyCodeMap(HLERequestContext& ctx) {
185 LOG_DEBUG(Service_SET, "Called {}", ctx.Description()); 185 LOG_DEBUG(Service_SET, "Called {}", ctx.Description());
186 GetKeyCodeMapImpl(ctx); 186 GetKeyCodeMapImpl(ctx);
187} 187}
188 188
189void SET::GetKeyCodeMap2(Kernel::HLERequestContext& ctx) { 189void SET::GetKeyCodeMap2(HLERequestContext& ctx) {
190 LOG_DEBUG(Service_SET, "Called {}", ctx.Description()); 190 LOG_DEBUG(Service_SET, "Called {}", ctx.Description());
191 GetKeyCodeMapImpl(ctx); 191 GetKeyCodeMapImpl(ctx);
192} 192}
193 193
194void SET::GetDeviceNickName(Kernel::HLERequestContext& ctx) { 194void SET::GetDeviceNickName(HLERequestContext& ctx) {
195 LOG_DEBUG(Service_SET, "called"); 195 LOG_DEBUG(Service_SET, "called");
196 IPC::ResponseBuilder rb{ctx, 2}; 196 IPC::ResponseBuilder rb{ctx, 2};
197 rb.Push(ResultSuccess); 197 rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h
index 375975711..7fd3a7654 100644
--- a/src/core/hle/service/set/set.h
+++ b/src/core/hle/service/set/set.h
@@ -40,17 +40,17 @@ public:
40 ~SET() override; 40 ~SET() override;
41 41
42private: 42private:
43 void GetLanguageCode(Kernel::HLERequestContext& ctx); 43 void GetLanguageCode(HLERequestContext& ctx);
44 void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx); 44 void GetAvailableLanguageCodes(HLERequestContext& ctx);
45 void MakeLanguageCode(Kernel::HLERequestContext& ctx); 45 void MakeLanguageCode(HLERequestContext& ctx);
46 void GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx); 46 void GetAvailableLanguageCodes2(HLERequestContext& ctx);
47 void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx); 47 void GetAvailableLanguageCodeCount(HLERequestContext& ctx);
48 void GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx); 48 void GetAvailableLanguageCodeCount2(HLERequestContext& ctx);
49 void GetQuestFlag(Kernel::HLERequestContext& ctx); 49 void GetQuestFlag(HLERequestContext& ctx);
50 void GetRegionCode(Kernel::HLERequestContext& ctx); 50 void GetRegionCode(HLERequestContext& ctx);
51 void GetKeyCodeMap(Kernel::HLERequestContext& ctx); 51 void GetKeyCodeMap(HLERequestContext& ctx);
52 void GetKeyCodeMap2(Kernel::HLERequestContext& ctx); 52 void GetKeyCodeMap2(HLERequestContext& ctx);
53 void GetDeviceNickName(Kernel::HLERequestContext& ctx); 53 void GetDeviceNickName(HLERequestContext& ctx);
54}; 54};
55 55
56} // namespace Service::Set 56} // namespace Service::Set
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index 94c20edda..2e38d1cfc 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -6,8 +6,8 @@
6#include "common/settings.h" 6#include "common/settings.h"
7#include "core/file_sys/errors.h" 7#include "core/file_sys/errors.h"
8#include "core/file_sys/system_archive/system_version.h" 8#include "core/file_sys/system_archive/system_version.h"
9#include "core/hle/ipc_helpers.h"
10#include "core/hle/service/filesystem/filesystem.h" 9#include "core/hle/service/filesystem/filesystem.h"
10#include "core/hle/service/ipc_helpers.h"
11#include "core/hle/service/set/set_sys.h" 11#include "core/hle/service/set/set_sys.h"
12 12
13namespace Service::Set { 13namespace Service::Set {
@@ -20,7 +20,7 @@ enum class GetFirmwareVersionType {
20 Version2, 20 Version2,
21}; 21};
22 22
23void GetFirmwareVersionImpl(Kernel::HLERequestContext& ctx, GetFirmwareVersionType type) { 23void GetFirmwareVersionImpl(HLERequestContext& ctx, GetFirmwareVersionType type) {
24 LOG_WARNING(Service_SET, "called - Using hardcoded firmware version '{}'", 24 LOG_WARNING(Service_SET, "called - Using hardcoded firmware version '{}'",
25 FileSys::SystemArchive::GetLongDisplayVersion()); 25 FileSys::SystemArchive::GetLongDisplayVersion());
26 26
@@ -73,17 +73,17 @@ void GetFirmwareVersionImpl(Kernel::HLERequestContext& ctx, GetFirmwareVersionTy
73} 73}
74} // Anonymous namespace 74} // Anonymous namespace
75 75
76void SET_SYS::GetFirmwareVersion(Kernel::HLERequestContext& ctx) { 76void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) {
77 LOG_DEBUG(Service_SET, "called"); 77 LOG_DEBUG(Service_SET, "called");
78 GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version1); 78 GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version1);
79} 79}
80 80
81void SET_SYS::GetFirmwareVersion2(Kernel::HLERequestContext& ctx) { 81void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) {
82 LOG_DEBUG(Service_SET, "called"); 82 LOG_DEBUG(Service_SET, "called");
83 GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version2); 83 GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version2);
84} 84}
85 85
86void SET_SYS::GetColorSetId(Kernel::HLERequestContext& ctx) { 86void SET_SYS::GetColorSetId(HLERequestContext& ctx) {
87 LOG_DEBUG(Service_SET, "called"); 87 LOG_DEBUG(Service_SET, "called");
88 88
89 IPC::ResponseBuilder rb{ctx, 3}; 89 IPC::ResponseBuilder rb{ctx, 3};
@@ -92,7 +92,7 @@ void SET_SYS::GetColorSetId(Kernel::HLERequestContext& ctx) {
92 rb.PushEnum(color_set); 92 rb.PushEnum(color_set);
93} 93}
94 94
95void SET_SYS::SetColorSetId(Kernel::HLERequestContext& ctx) { 95void SET_SYS::SetColorSetId(HLERequestContext& ctx) {
96 LOG_DEBUG(Service_SET, "called"); 96 LOG_DEBUG(Service_SET, "called");
97 97
98 IPC::RequestParser rp{ctx}; 98 IPC::RequestParser rp{ctx};
@@ -126,7 +126,7 @@ static Settings GetSettings() {
126 return ret; 126 return ret;
127} 127}
128 128
129void SET_SYS::GetSettingsItemValueSize(Kernel::HLERequestContext& ctx) { 129void SET_SYS::GetSettingsItemValueSize(HLERequestContext& ctx) {
130 LOG_DEBUG(Service_SET, "called"); 130 LOG_DEBUG(Service_SET, "called");
131 131
132 // The category of the setting. This corresponds to the top-level keys of 132 // The category of the setting. This corresponds to the top-level keys of
@@ -151,7 +151,7 @@ void SET_SYS::GetSettingsItemValueSize(Kernel::HLERequestContext& ctx) {
151 rb.Push(response_size); 151 rb.Push(response_size);
152} 152}
153 153
154void SET_SYS::GetSettingsItemValue(Kernel::HLERequestContext& ctx) { 154void SET_SYS::GetSettingsItemValue(HLERequestContext& ctx) {
155 LOG_DEBUG(Service_SET, "called"); 155 LOG_DEBUG(Service_SET, "called");
156 156
157 // The category of the setting. This corresponds to the top-level keys of 157 // The category of the setting. This corresponds to the top-level keys of
@@ -177,7 +177,7 @@ void SET_SYS::GetSettingsItemValue(Kernel::HLERequestContext& ctx) {
177 rb.Push(response); 177 rb.Push(response);
178} 178}
179 179
180void SET_SYS::GetDeviceNickName(Kernel::HLERequestContext& ctx) { 180void SET_SYS::GetDeviceNickName(HLERequestContext& ctx) {
181 LOG_DEBUG(Service_SET, "called"); 181 LOG_DEBUG(Service_SET, "called");
182 IPC::ResponseBuilder rb{ctx, 2}; 182 IPC::ResponseBuilder rb{ctx, 2};
183 rb.Push(ResultSuccess); 183 rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/set_sys.h
index 464ac3da1..1efbcc97a 100644
--- a/src/core/hle/service/set/set_sys.h
+++ b/src/core/hle/service/set/set_sys.h
@@ -23,13 +23,13 @@ private:
23 BasicBlack = 1, 23 BasicBlack = 1,
24 }; 24 };
25 25
26 void GetSettingsItemValueSize(Kernel::HLERequestContext& ctx); 26 void GetSettingsItemValueSize(HLERequestContext& ctx);
27 void GetSettingsItemValue(Kernel::HLERequestContext& ctx); 27 void GetSettingsItemValue(HLERequestContext& ctx);
28 void GetFirmwareVersion(Kernel::HLERequestContext& ctx); 28 void GetFirmwareVersion(HLERequestContext& ctx);
29 void GetFirmwareVersion2(Kernel::HLERequestContext& ctx); 29 void GetFirmwareVersion2(HLERequestContext& ctx);
30 void GetColorSetId(Kernel::HLERequestContext& ctx); 30 void GetColorSetId(HLERequestContext& ctx);
31 void SetColorSetId(Kernel::HLERequestContext& ctx); 31 void SetColorSetId(HLERequestContext& ctx);
32 void GetDeviceNickName(Kernel::HLERequestContext& ctx); 32 void GetDeviceNickName(HLERequestContext& ctx);
33 33
34 ColorSet color_set = ColorSet::BasicWhite; 34 ColorSet color_set = ColorSet::BasicWhite;
35}; 35};
diff --git a/src/core/hle/service/set/settings.cpp b/src/core/hle/service/set/settings.cpp
index 4ebc2a0ec..c48844f77 100644
--- a/src/core/hle/service/set/settings.cpp
+++ b/src/core/hle/service/set/settings.cpp
@@ -1,20 +1,23 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/server_manager.h"
4#include "core/hle/service/set/set.h" 5#include "core/hle/service/set/set.h"
5#include "core/hle/service/set/set_cal.h" 6#include "core/hle/service/set/set_cal.h"
6#include "core/hle/service/set/set_fd.h" 7#include "core/hle/service/set/set_fd.h"
7#include "core/hle/service/set/set_sys.h" 8#include "core/hle/service/set/set_sys.h"
8#include "core/hle/service/set/settings.h" 9#include "core/hle/service/set/settings.h"
9#include "core/hle/service/sm/sm.h"
10 10
11namespace Service::Set { 11namespace Service::Set {
12 12
13void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 13void LoopProcess(Core::System& system) {
14 std::make_shared<SET>(system)->InstallAsService(service_manager); 14 auto server_manager = std::make_unique<ServerManager>(system);
15 std::make_shared<SET_CAL>(system)->InstallAsService(service_manager); 15
16 std::make_shared<SET_FD>(system)->InstallAsService(service_manager); 16 server_manager->RegisterNamedService("set", std::make_shared<SET>(system));
17 std::make_shared<SET_SYS>(system)->InstallAsService(service_manager); 17 server_manager->RegisterNamedService("set:cal", std::make_shared<SET_CAL>(system));
18 server_manager->RegisterNamedService("set:fd", std::make_shared<SET_FD>(system));
19 server_manager->RegisterNamedService("set:sys", std::make_shared<SET_SYS>(system));
20 ServerManager::RunServer(std::move(server_manager));
18} 21}
19 22
20} // namespace Service::Set 23} // namespace Service::Set
diff --git a/src/core/hle/service/set/settings.h b/src/core/hle/service/set/settings.h
index 6cd7d634c..03cd4bb66 100644
--- a/src/core/hle/service/set/settings.h
+++ b/src/core/hle/service/set/settings.h
@@ -7,13 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::Set { 10namespace Service::Set {
15 11
16/// Registers all Settings services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::Set 14} // namespace Service::Set
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 84720094f..b4046d3ce 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -5,62 +5,60 @@
5#include "common/assert.h" 5#include "common/assert.h"
6#include "common/scope_exit.h" 6#include "common/scope_exit.h"
7#include "core/core.h" 7#include "core/core.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/k_client_port.h" 8#include "core/hle/kernel/k_client_port.h"
10#include "core/hle/kernel/k_client_session.h" 9#include "core/hle/kernel/k_client_session.h"
11#include "core/hle/kernel/k_port.h" 10#include "core/hle/kernel/k_port.h"
12#include "core/hle/kernel/k_scoped_resource_reservation.h" 11#include "core/hle/kernel/k_scoped_resource_reservation.h"
13#include "core/hle/kernel/k_server_port.h" 12#include "core/hle/kernel/k_server_port.h"
14#include "core/hle/result.h" 13#include "core/hle/result.h"
14#include "core/hle/service/ipc_helpers.h"
15#include "core/hle/service/server_manager.h"
15#include "core/hle/service/sm/sm.h" 16#include "core/hle/service/sm/sm.h"
16#include "core/hle/service/sm/sm_controller.h" 17#include "core/hle/service/sm/sm_controller.h"
17 18
18namespace Service::SM { 19namespace Service::SM {
19 20
20constexpr Result ERR_NOT_INITIALIZED(ErrorModule::SM, 2); 21constexpr Result ResultInvalidClient(ErrorModule::SM, 2);
21constexpr Result ERR_ALREADY_REGISTERED(ErrorModule::SM, 4); 22constexpr Result ResultAlreadyRegistered(ErrorModule::SM, 4);
22constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6); 23constexpr Result ResultInvalidServiceName(ErrorModule::SM, 6);
23constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); 24constexpr Result ResultNotRegistered(ErrorModule::SM, 7);
24 25
25ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {} 26ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {
27 controller_interface = std::make_unique<Controller>(kernel.System());
28}
26 29
27ServiceManager::~ServiceManager() { 30ServiceManager::~ServiceManager() {
28 for (auto& [name, port] : service_ports) { 31 for (auto& [name, port] : service_ports) {
29 port->GetClientPort().Close(); 32 port->GetClientPort().Close();
30 port->GetServerPort().Close(); 33 port->GetServerPort().Close();
31 } 34 }
35
36 if (deferral_event) {
37 deferral_event->Close();
38 }
32} 39}
33 40
34void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) { 41void ServiceManager::InvokeControlRequest(HLERequestContext& context) {
35 controller_interface->InvokeRequest(context); 42 controller_interface->InvokeRequest(context);
36} 43}
37 44
38static Result ValidateServiceName(const std::string& name) { 45static Result ValidateServiceName(const std::string& name) {
39 if (name.empty() || name.size() > 8) { 46 if (name.empty() || name.size() > 8) {
40 LOG_ERROR(Service_SM, "Invalid service name! service={}", name); 47 LOG_ERROR(Service_SM, "Invalid service name! service={}", name);
41 return ERR_INVALID_NAME; 48 return Service::SM::ResultInvalidServiceName;
42 } 49 }
43 return ResultSuccess; 50 return ResultSuccess;
44} 51}
45 52
46Kernel::KClientPort& ServiceManager::InterfaceFactory(ServiceManager& self, Core::System& system) {
47 self.sm_interface = std::make_shared<SM>(self, system);
48 self.controller_interface = std::make_unique<Controller>(system);
49 return self.sm_interface->CreatePort();
50}
51
52void ServiceManager::SessionHandler(ServiceManager& self, Kernel::KServerPort* server_port) {
53 self.sm_interface->AcceptSession(server_port);
54}
55
56Result ServiceManager::RegisterService(std::string name, u32 max_sessions, 53Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
57 Kernel::SessionRequestHandlerPtr handler) { 54 SessionRequestHandlerPtr handler) {
58 55
59 CASCADE_CODE(ValidateServiceName(name)); 56 CASCADE_CODE(ValidateServiceName(name));
60 57
58 std::scoped_lock lk{lock};
61 if (registered_services.find(name) != registered_services.end()) { 59 if (registered_services.find(name) != registered_services.end()) {
62 LOG_ERROR(Service_SM, "Service is already registered! service={}", name); 60 LOG_ERROR(Service_SM, "Service is already registered! service={}", name);
63 return ERR_ALREADY_REGISTERED; 61 return Service::SM::ResultAlreadyRegistered;
64 } 62 }
65 63
66 auto* port = Kernel::KPort::Create(kernel); 64 auto* port = Kernel::KPort::Create(kernel);
@@ -68,6 +66,9 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
68 66
69 service_ports.emplace(name, port); 67 service_ports.emplace(name, port);
70 registered_services.emplace(name, handler); 68 registered_services.emplace(name, handler);
69 if (deferral_event) {
70 deferral_event->Signal();
71 }
71 72
72 return ResultSuccess; 73 return ResultSuccess;
73} 74}
@@ -75,10 +76,11 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
75Result ServiceManager::UnregisterService(const std::string& name) { 76Result ServiceManager::UnregisterService(const std::string& name) {
76 CASCADE_CODE(ValidateServiceName(name)); 77 CASCADE_CODE(ValidateServiceName(name));
77 78
79 std::scoped_lock lk{lock};
78 const auto iter = registered_services.find(name); 80 const auto iter = registered_services.find(name);
79 if (iter == registered_services.end()) { 81 if (iter == registered_services.end()) {
80 LOG_ERROR(Service_SM, "Server is not registered! service={}", name); 82 LOG_ERROR(Service_SM, "Server is not registered! service={}", name);
81 return ERR_SERVICE_NOT_REGISTERED; 83 return Service::SM::ResultNotRegistered;
82 } 84 }
83 85
84 registered_services.erase(iter); 86 registered_services.erase(iter);
@@ -89,10 +91,12 @@ Result ServiceManager::UnregisterService(const std::string& name) {
89 91
90ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) { 92ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) {
91 CASCADE_CODE(ValidateServiceName(name)); 93 CASCADE_CODE(ValidateServiceName(name));
94
95 std::scoped_lock lk{lock};
92 auto it = service_ports.find(name); 96 auto it = service_ports.find(name);
93 if (it == service_ports.end()) { 97 if (it == service_ports.end()) {
94 LOG_ERROR(Service_SM, "Server is not registered! service={}", name); 98 LOG_WARNING(Service_SM, "Server is not registered! service={}", name);
95 return ERR_SERVICE_NOT_REGISTERED; 99 return Service::SM::ResultNotRegistered;
96 } 100 }
97 101
98 return it->second; 102 return it->second;
@@ -105,17 +109,22 @@ ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name
105 * Outputs: 109 * Outputs:
106 * 0: Result 110 * 0: Result
107 */ 111 */
108void SM::Initialize(Kernel::HLERequestContext& ctx) { 112void SM::Initialize(HLERequestContext& ctx) {
109 LOG_DEBUG(Service_SM, "called"); 113 LOG_DEBUG(Service_SM, "called");
110 114
111 is_initialized = true; 115 ctx.GetManager()->SetIsInitializedForSm();
112 116
113 IPC::ResponseBuilder rb{ctx, 2}; 117 IPC::ResponseBuilder rb{ctx, 2};
114 rb.Push(ResultSuccess); 118 rb.Push(ResultSuccess);
115} 119}
116 120
117void SM::GetService(Kernel::HLERequestContext& ctx) { 121void SM::GetService(HLERequestContext& ctx) {
118 auto result = GetServiceImpl(ctx); 122 auto result = GetServiceImpl(ctx);
123 if (ctx.GetIsDeferred()) {
124 // Don't overwrite the command buffer.
125 return;
126 }
127
119 if (result.Succeeded()) { 128 if (result.Succeeded()) {
120 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 129 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
121 rb.Push(result.Code()); 130 rb.Push(result.Code());
@@ -126,8 +135,13 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
126 } 135 }
127} 136}
128 137
129void SM::GetServiceTipc(Kernel::HLERequestContext& ctx) { 138void SM::GetServiceTipc(HLERequestContext& ctx) {
130 auto result = GetServiceImpl(ctx); 139 auto result = GetServiceImpl(ctx);
140 if (ctx.GetIsDeferred()) {
141 // Don't overwrite the command buffer.
142 return;
143 }
144
131 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 145 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
132 rb.Push(result.Code()); 146 rb.Push(result.Code());
133 rb.PushMoveObjects(result.Succeeded() ? result.Unwrap() : nullptr); 147 rb.PushMoveObjects(result.Succeeded() ? result.Unwrap() : nullptr);
@@ -144,9 +158,9 @@ static std::string PopServiceName(IPC::RequestParser& rp) {
144 return result; 158 return result;
145} 159}
146 160
147ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext& ctx) { 161ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(HLERequestContext& ctx) {
148 if (!is_initialized) { 162 if (!ctx.GetManager()->GetIsInitializedForSm()) {
149 return ERR_NOT_INITIALIZED; 163 return Service::SM::ResultInvalidClient;
150 } 164 }
151 165
152 IPC::RequestParser rp{ctx}; 166 IPC::RequestParser rp{ctx};
@@ -154,10 +168,15 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
154 168
155 // Find the named port. 169 // Find the named port.
156 auto port_result = service_manager.GetServicePort(name); 170 auto port_result = service_manager.GetServicePort(name);
157 auto service = service_manager.GetService<Kernel::SessionRequestHandler>(name); 171 if (port_result.Code() == Service::SM::ResultInvalidServiceName) {
158 if (port_result.Failed() || !service) { 172 LOG_ERROR(Service_SM, "Invalid service name '{}'", name);
159 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw); 173 return Service::SM::ResultInvalidServiceName;
160 return port_result.Code(); 174 }
175
176 if (port_result.Failed()) {
177 LOG_INFO(Service_SM, "Waiting for service {} to become available", name);
178 ctx.SetIsDeferred();
179 return Service::SM::ResultNotRegistered;
161 } 180 }
162 auto& port = port_result.Unwrap(); 181 auto& port = port_result.Unwrap();
163 182
@@ -167,14 +186,13 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
167 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); 186 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw);
168 return result; 187 return result;
169 } 188 }
170 service->AcceptSession(&port->GetServerPort());
171 189
172 LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId()); 190 LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId());
173 191
174 return session; 192 return session;
175} 193}
176 194
177void SM::RegisterService(Kernel::HLERequestContext& ctx) { 195void SM::RegisterService(HLERequestContext& ctx) {
178 IPC::RequestParser rp{ctx}; 196 IPC::RequestParser rp{ctx};
179 std::string name(PopServiceName(rp)); 197 std::string name(PopServiceName(rp));
180 198
@@ -201,7 +219,7 @@ void SM::RegisterService(Kernel::HLERequestContext& ctx) {
201 rb.PushMoveObjects(port->GetServerPort()); 219 rb.PushMoveObjects(port->GetServerPort());
202} 220}
203 221
204void SM::UnregisterService(Kernel::HLERequestContext& ctx) { 222void SM::UnregisterService(HLERequestContext& ctx) {
205 IPC::RequestParser rp{ctx}; 223 IPC::RequestParser rp{ctx};
206 std::string name(PopServiceName(rp)); 224 std::string name(PopServiceName(rp));
207 225
@@ -212,7 +230,7 @@ void SM::UnregisterService(Kernel::HLERequestContext& ctx) {
212} 230}
213 231
214SM::SM(ServiceManager& service_manager_, Core::System& system_) 232SM::SM(ServiceManager& service_manager_, Core::System& system_)
215 : ServiceFramework{system_, "sm:", ServiceThreadType::Default, 4}, 233 : ServiceFramework{system_, "sm:", 4},
216 service_manager{service_manager_}, kernel{system_.Kernel()} { 234 service_manager{service_manager_}, kernel{system_.Kernel()} {
217 RegisterHandlers({ 235 RegisterHandlers({
218 {0, &SM::Initialize, "Initialize"}, 236 {0, &SM::Initialize, "Initialize"},
@@ -232,4 +250,16 @@ SM::SM(ServiceManager& service_manager_, Core::System& system_)
232 250
233SM::~SM() = default; 251SM::~SM() = default;
234 252
253void LoopProcess(Core::System& system) {
254 auto& service_manager = system.ServiceManager();
255 auto server_manager = std::make_unique<ServerManager>(system);
256
257 Kernel::KEvent* deferral_event{};
258 server_manager->ManageDeferral(&deferral_event);
259 service_manager.SetDeferralEvent(deferral_event);
260
261 server_manager->ManageNamedPort("sm:", std::make_shared<SM>(system.ServiceManager(), system));
262 ServerManager::RunServer(std::move(server_manager));
263}
264
235} // namespace Service::SM 265} // namespace Service::SM
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index 02a5dde9e..6697f4007 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -4,6 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include <memory> 6#include <memory>
7#include <mutex>
7#include <string> 8#include <string>
8#include <unordered_map> 9#include <unordered_map>
9 10
@@ -35,33 +36,28 @@ public:
35 ~SM() override; 36 ~SM() override;
36 37
37private: 38private:
38 void Initialize(Kernel::HLERequestContext& ctx); 39 void Initialize(HLERequestContext& ctx);
39 void GetService(Kernel::HLERequestContext& ctx); 40 void GetService(HLERequestContext& ctx);
40 void GetServiceTipc(Kernel::HLERequestContext& ctx); 41 void GetServiceTipc(HLERequestContext& ctx);
41 void RegisterService(Kernel::HLERequestContext& ctx); 42 void RegisterService(HLERequestContext& ctx);
42 void UnregisterService(Kernel::HLERequestContext& ctx); 43 void UnregisterService(HLERequestContext& ctx);
43 44
44 ResultVal<Kernel::KClientSession*> GetServiceImpl(Kernel::HLERequestContext& ctx); 45 ResultVal<Kernel::KClientSession*> GetServiceImpl(HLERequestContext& ctx);
45 46
46 ServiceManager& service_manager; 47 ServiceManager& service_manager;
47 bool is_initialized{};
48 Kernel::KernelCore& kernel; 48 Kernel::KernelCore& kernel;
49}; 49};
50 50
51class ServiceManager { 51class ServiceManager {
52public: 52public:
53 static Kernel::KClientPort& InterfaceFactory(ServiceManager& self, Core::System& system);
54 static void SessionHandler(ServiceManager& self, Kernel::KServerPort* server_port);
55
56 explicit ServiceManager(Kernel::KernelCore& kernel_); 53 explicit ServiceManager(Kernel::KernelCore& kernel_);
57 ~ServiceManager(); 54 ~ServiceManager();
58 55
59 Result RegisterService(std::string name, u32 max_sessions, 56 Result RegisterService(std::string name, u32 max_sessions, SessionRequestHandlerPtr handler);
60 Kernel::SessionRequestHandlerPtr handler);
61 Result UnregisterService(const std::string& name); 57 Result UnregisterService(const std::string& name);
62 ResultVal<Kernel::KPort*> GetServicePort(const std::string& name); 58 ResultVal<Kernel::KPort*> GetServicePort(const std::string& name);
63 59
64 template <Common::DerivedFrom<Kernel::SessionRequestHandler> T> 60 template <Common::DerivedFrom<SessionRequestHandler> T>
65 std::shared_ptr<T> GetService(const std::string& service_name) const { 61 std::shared_ptr<T> GetService(const std::string& service_name) const {
66 auto service = registered_services.find(service_name); 62 auto service = registered_services.find(service_name);
67 if (service == registered_services.end()) { 63 if (service == registered_services.end()) {
@@ -71,18 +67,27 @@ public:
71 return std::static_pointer_cast<T>(service->second); 67 return std::static_pointer_cast<T>(service->second);
72 } 68 }
73 69
74 void InvokeControlRequest(Kernel::HLERequestContext& context); 70 void InvokeControlRequest(HLERequestContext& context);
71
72 void SetDeferralEvent(Kernel::KEvent* deferral_event_) {
73 deferral_event = deferral_event_;
74 }
75 75
76private: 76private:
77 std::shared_ptr<SM> sm_interface; 77 std::shared_ptr<SM> sm_interface;
78 std::unique_ptr<Controller> controller_interface; 78 std::unique_ptr<Controller> controller_interface;
79 79
80 /// Map of registered services, retrieved using GetServicePort. 80 /// Map of registered services, retrieved using GetServicePort.
81 std::unordered_map<std::string, Kernel::SessionRequestHandlerPtr> registered_services; 81 std::mutex lock;
82 std::unordered_map<std::string, SessionRequestHandlerPtr> registered_services;
82 std::unordered_map<std::string, Kernel::KPort*> service_ports; 83 std::unordered_map<std::string, Kernel::KPort*> service_ports;
83 84
84 /// Kernel context 85 /// Kernel context
85 Kernel::KernelCore& kernel; 86 Kernel::KernelCore& kernel;
87 Kernel::KEvent* deferral_event{};
86}; 88};
87 89
90/// Runs SM services.
91void LoopProcess(Core::System& system);
92
88} // namespace Service::SM 93} // namespace Service::SM
diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp
index 1cf9dd1c4..0111c8d7f 100644
--- a/src/core/hle/service/sm/sm_controller.cpp
+++ b/src/core/hle/service/sm/sm_controller.cpp
@@ -4,17 +4,18 @@
4#include "common/assert.h" 4#include "common/assert.h"
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "core/core.h" 6#include "core/core.h"
7#include "core/hle/ipc_helpers.h"
8#include "core/hle/kernel/k_client_port.h" 7#include "core/hle/kernel/k_client_port.h"
9#include "core/hle/kernel/k_port.h" 8#include "core/hle/kernel/k_port.h"
10#include "core/hle/kernel/k_scoped_resource_reservation.h" 9#include "core/hle/kernel/k_scoped_resource_reservation.h"
11#include "core/hle/kernel/k_server_session.h" 10#include "core/hle/kernel/k_server_session.h"
12#include "core/hle/kernel/k_session.h" 11#include "core/hle/kernel/k_session.h"
12#include "core/hle/service/ipc_helpers.h"
13#include "core/hle/service/server_manager.h"
13#include "core/hle/service/sm/sm_controller.h" 14#include "core/hle/service/sm/sm_controller.h"
14 15
15namespace Service::SM { 16namespace Service::SM {
16 17
17void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) { 18void Controller::ConvertCurrentObjectToDomain(HLERequestContext& ctx) {
18 ASSERT_MSG(!ctx.GetManager()->IsDomain(), "Session is already a domain"); 19 ASSERT_MSG(!ctx.GetManager()->IsDomain(), "Session is already a domain");
19 LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetId()); 20 LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetId());
20 ctx.GetManager()->ConvertToDomainOnRequestEnd(); 21 ctx.GetManager()->ConvertToDomainOnRequestEnd();
@@ -24,7 +25,7 @@ void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) {
24 rb.Push<u32>(1); // Converted sessions start with 1 request handler 25 rb.Push<u32>(1); // Converted sessions start with 1 request handler
25} 26}
26 27
27void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { 28void Controller::CloneCurrentObject(HLERequestContext& ctx) {
28 LOG_DEBUG(Service, "called"); 29 LOG_DEBUG(Service, "called");
29 30
30 auto& process = *ctx.GetThread().GetOwnerProcess(); 31 auto& process = *ctx.GetThread().GetOwnerProcess();
@@ -48,9 +49,9 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
48 // Commit the session reservation. 49 // Commit the session reservation.
49 session_reservation.Commit(); 50 session_reservation.Commit();
50 51
51 // Register with manager. 52 // Register with server manager.
52 session_manager->SessionHandler().RegisterSession(&session->GetServerSession(), 53 session_manager->GetServerManager().RegisterSession(&session->GetServerSession(),
53 session_manager); 54 session_manager);
54 55
55 // We succeeded. 56 // We succeeded.
56 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 57 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
@@ -58,13 +59,13 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
58 rb.PushMoveObjects(session->GetClientSession()); 59 rb.PushMoveObjects(session->GetClientSession());
59} 60}
60 61
61void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { 62void Controller::CloneCurrentObjectEx(HLERequestContext& ctx) {
62 LOG_DEBUG(Service, "called"); 63 LOG_DEBUG(Service, "called");
63 64
64 CloneCurrentObject(ctx); 65 CloneCurrentObject(ctx);
65} 66}
66 67
67void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { 68void Controller::QueryPointerBufferSize(HLERequestContext& ctx) {
68 LOG_WARNING(Service, "(STUBBED) called"); 69 LOG_WARNING(Service, "(STUBBED) called");
69 70
70 IPC::ResponseBuilder rb{ctx, 3}; 71 IPC::ResponseBuilder rb{ctx, 3};
diff --git a/src/core/hle/service/sm/sm_controller.h b/src/core/hle/service/sm/sm_controller.h
index ed386f660..4e748b36d 100644
--- a/src/core/hle/service/sm/sm_controller.h
+++ b/src/core/hle/service/sm/sm_controller.h
@@ -17,10 +17,10 @@ public:
17 ~Controller() override; 17 ~Controller() override;
18 18
19private: 19private:
20 void ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx); 20 void ConvertCurrentObjectToDomain(HLERequestContext& ctx);
21 void CloneCurrentObject(Kernel::HLERequestContext& ctx); 21 void CloneCurrentObject(HLERequestContext& ctx);
22 void CloneCurrentObjectEx(Kernel::HLERequestContext& ctx); 22 void CloneCurrentObjectEx(HLERequestContext& ctx);
23 void QueryPointerBufferSize(Kernel::HLERequestContext& ctx); 23 void QueryPointerBufferSize(HLERequestContext& ctx);
24}; 24};
25 25
26} // namespace Service::SM 26} // namespace Service::SM
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index 330a66409..bce45d321 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -11,8 +11,8 @@
11#include "common/microprofile.h" 11#include "common/microprofile.h"
12#include "common/socket_types.h" 12#include "common/socket_types.h"
13#include "core/core.h" 13#include "core/core.h"
14#include "core/hle/ipc_helpers.h"
15#include "core/hle/kernel/k_thread.h" 14#include "core/hle/kernel/k_thread.h"
15#include "core/hle/service/ipc_helpers.h"
16#include "core/hle/service/sockets/bsd.h" 16#include "core/hle/service/sockets/bsd.h"
17#include "core/hle/service/sockets/sockets_translate.h" 17#include "core/hle/service/sockets/sockets_translate.h"
18#include "core/internal_network/network.h" 18#include "core/internal_network/network.h"
@@ -42,7 +42,7 @@ void BSD::PollWork::Execute(BSD* bsd) {
42 std::tie(ret, bsd_errno) = bsd->PollImpl(write_buffer, read_buffer, nfds, timeout); 42 std::tie(ret, bsd_errno) = bsd->PollImpl(write_buffer, read_buffer, nfds, timeout);
43} 43}
44 44
45void BSD::PollWork::Response(Kernel::HLERequestContext& ctx) { 45void BSD::PollWork::Response(HLERequestContext& ctx) {
46 if (write_buffer.size() > 0) { 46 if (write_buffer.size() > 0) {
47 ctx.WriteBuffer(write_buffer); 47 ctx.WriteBuffer(write_buffer);
48 } 48 }
@@ -57,7 +57,7 @@ void BSD::AcceptWork::Execute(BSD* bsd) {
57 std::tie(ret, bsd_errno) = bsd->AcceptImpl(fd, write_buffer); 57 std::tie(ret, bsd_errno) = bsd->AcceptImpl(fd, write_buffer);
58} 58}
59 59
60void BSD::AcceptWork::Response(Kernel::HLERequestContext& ctx) { 60void BSD::AcceptWork::Response(HLERequestContext& ctx) {
61 if (write_buffer.size() > 0) { 61 if (write_buffer.size() > 0) {
62 ctx.WriteBuffer(write_buffer); 62 ctx.WriteBuffer(write_buffer);
63 } 63 }
@@ -73,7 +73,7 @@ void BSD::ConnectWork::Execute(BSD* bsd) {
73 bsd_errno = bsd->ConnectImpl(fd, addr); 73 bsd_errno = bsd->ConnectImpl(fd, addr);
74} 74}
75 75
76void BSD::ConnectWork::Response(Kernel::HLERequestContext& ctx) { 76void BSD::ConnectWork::Response(HLERequestContext& ctx) {
77 IPC::ResponseBuilder rb{ctx, 4}; 77 IPC::ResponseBuilder rb{ctx, 4};
78 rb.Push(ResultSuccess); 78 rb.Push(ResultSuccess);
79 rb.Push<s32>(bsd_errno == Errno::SUCCESS ? 0 : -1); 79 rb.Push<s32>(bsd_errno == Errno::SUCCESS ? 0 : -1);
@@ -84,7 +84,7 @@ void BSD::RecvWork::Execute(BSD* bsd) {
84 std::tie(ret, bsd_errno) = bsd->RecvImpl(fd, flags, message); 84 std::tie(ret, bsd_errno) = bsd->RecvImpl(fd, flags, message);
85} 85}
86 86
87void BSD::RecvWork::Response(Kernel::HLERequestContext& ctx) { 87void BSD::RecvWork::Response(HLERequestContext& ctx) {
88 ctx.WriteBuffer(message); 88 ctx.WriteBuffer(message);
89 89
90 IPC::ResponseBuilder rb{ctx, 4}; 90 IPC::ResponseBuilder rb{ctx, 4};
@@ -97,7 +97,7 @@ void BSD::RecvFromWork::Execute(BSD* bsd) {
97 std::tie(ret, bsd_errno) = bsd->RecvFromImpl(fd, flags, message, addr); 97 std::tie(ret, bsd_errno) = bsd->RecvFromImpl(fd, flags, message, addr);
98} 98}
99 99
100void BSD::RecvFromWork::Response(Kernel::HLERequestContext& ctx) { 100void BSD::RecvFromWork::Response(HLERequestContext& ctx) {
101 ctx.WriteBuffer(message, 0); 101 ctx.WriteBuffer(message, 0);
102 if (!addr.empty()) { 102 if (!addr.empty()) {
103 ctx.WriteBuffer(addr, 1); 103 ctx.WriteBuffer(addr, 1);
@@ -114,7 +114,7 @@ void BSD::SendWork::Execute(BSD* bsd) {
114 std::tie(ret, bsd_errno) = bsd->SendImpl(fd, flags, message); 114 std::tie(ret, bsd_errno) = bsd->SendImpl(fd, flags, message);
115} 115}
116 116
117void BSD::SendWork::Response(Kernel::HLERequestContext& ctx) { 117void BSD::SendWork::Response(HLERequestContext& ctx) {
118 IPC::ResponseBuilder rb{ctx, 4}; 118 IPC::ResponseBuilder rb{ctx, 4};
119 rb.Push(ResultSuccess); 119 rb.Push(ResultSuccess);
120 rb.Push<s32>(ret); 120 rb.Push<s32>(ret);
@@ -125,14 +125,14 @@ void BSD::SendToWork::Execute(BSD* bsd) {
125 std::tie(ret, bsd_errno) = bsd->SendToImpl(fd, flags, message, addr); 125 std::tie(ret, bsd_errno) = bsd->SendToImpl(fd, flags, message, addr);
126} 126}
127 127
128void BSD::SendToWork::Response(Kernel::HLERequestContext& ctx) { 128void BSD::SendToWork::Response(HLERequestContext& ctx) {
129 IPC::ResponseBuilder rb{ctx, 4}; 129 IPC::ResponseBuilder rb{ctx, 4};
130 rb.Push(ResultSuccess); 130 rb.Push(ResultSuccess);
131 rb.Push<s32>(ret); 131 rb.Push<s32>(ret);
132 rb.PushEnum(bsd_errno); 132 rb.PushEnum(bsd_errno);
133} 133}
134 134
135void BSD::RegisterClient(Kernel::HLERequestContext& ctx) { 135void BSD::RegisterClient(HLERequestContext& ctx) {
136 LOG_WARNING(Service, "(STUBBED) called"); 136 LOG_WARNING(Service, "(STUBBED) called");
137 137
138 IPC::ResponseBuilder rb{ctx, 3}; 138 IPC::ResponseBuilder rb{ctx, 3};
@@ -141,7 +141,7 @@ void BSD::RegisterClient(Kernel::HLERequestContext& ctx) {
141 rb.Push<s32>(0); // bsd errno 141 rb.Push<s32>(0); // bsd errno
142} 142}
143 143
144void BSD::StartMonitoring(Kernel::HLERequestContext& ctx) { 144void BSD::StartMonitoring(HLERequestContext& ctx) {
145 LOG_WARNING(Service, "(STUBBED) called"); 145 LOG_WARNING(Service, "(STUBBED) called");
146 146
147 IPC::ResponseBuilder rb{ctx, 2}; 147 IPC::ResponseBuilder rb{ctx, 2};
@@ -149,7 +149,7 @@ void BSD::StartMonitoring(Kernel::HLERequestContext& ctx) {
149 rb.Push(ResultSuccess); 149 rb.Push(ResultSuccess);
150} 150}
151 151
152void BSD::Socket(Kernel::HLERequestContext& ctx) { 152void BSD::Socket(HLERequestContext& ctx) {
153 IPC::RequestParser rp{ctx}; 153 IPC::RequestParser rp{ctx};
154 const u32 domain = rp.Pop<u32>(); 154 const u32 domain = rp.Pop<u32>();
155 const u32 type = rp.Pop<u32>(); 155 const u32 type = rp.Pop<u32>();
@@ -166,7 +166,7 @@ void BSD::Socket(Kernel::HLERequestContext& ctx) {
166 rb.PushEnum(bsd_errno); 166 rb.PushEnum(bsd_errno);
167} 167}
168 168
169void BSD::Select(Kernel::HLERequestContext& ctx) { 169void BSD::Select(HLERequestContext& ctx) {
170 LOG_WARNING(Service, "(STUBBED) called"); 170 LOG_WARNING(Service, "(STUBBED) called");
171 171
172 IPC::ResponseBuilder rb{ctx, 4}; 172 IPC::ResponseBuilder rb{ctx, 4};
@@ -176,7 +176,7 @@ void BSD::Select(Kernel::HLERequestContext& ctx) {
176 rb.Push<u32>(0); // bsd errno 176 rb.Push<u32>(0); // bsd errno
177} 177}
178 178
179void BSD::Poll(Kernel::HLERequestContext& ctx) { 179void BSD::Poll(HLERequestContext& ctx) {
180 IPC::RequestParser rp{ctx}; 180 IPC::RequestParser rp{ctx};
181 const s32 nfds = rp.Pop<s32>(); 181 const s32 nfds = rp.Pop<s32>();
182 const s32 timeout = rp.Pop<s32>(); 182 const s32 timeout = rp.Pop<s32>();
@@ -191,7 +191,7 @@ void BSD::Poll(Kernel::HLERequestContext& ctx) {
191 }); 191 });
192} 192}
193 193
194void BSD::Accept(Kernel::HLERequestContext& ctx) { 194void BSD::Accept(HLERequestContext& ctx) {
195 IPC::RequestParser rp{ctx}; 195 IPC::RequestParser rp{ctx};
196 const s32 fd = rp.Pop<s32>(); 196 const s32 fd = rp.Pop<s32>();
197 197
@@ -203,7 +203,7 @@ void BSD::Accept(Kernel::HLERequestContext& ctx) {
203 }); 203 });
204} 204}
205 205
206void BSD::Bind(Kernel::HLERequestContext& ctx) { 206void BSD::Bind(HLERequestContext& ctx) {
207 IPC::RequestParser rp{ctx}; 207 IPC::RequestParser rp{ctx};
208 const s32 fd = rp.Pop<s32>(); 208 const s32 fd = rp.Pop<s32>();
209 209
@@ -211,7 +211,7 @@ void BSD::Bind(Kernel::HLERequestContext& ctx) {
211 BuildErrnoResponse(ctx, BindImpl(fd, ctx.ReadBuffer())); 211 BuildErrnoResponse(ctx, BindImpl(fd, ctx.ReadBuffer()));
212} 212}
213 213
214void BSD::Connect(Kernel::HLERequestContext& ctx) { 214void BSD::Connect(HLERequestContext& ctx) {
215 IPC::RequestParser rp{ctx}; 215 IPC::RequestParser rp{ctx};
216 const s32 fd = rp.Pop<s32>(); 216 const s32 fd = rp.Pop<s32>();
217 217
@@ -223,7 +223,7 @@ void BSD::Connect(Kernel::HLERequestContext& ctx) {
223 }); 223 });
224} 224}
225 225
226void BSD::GetPeerName(Kernel::HLERequestContext& ctx) { 226void BSD::GetPeerName(HLERequestContext& ctx) {
227 IPC::RequestParser rp{ctx}; 227 IPC::RequestParser rp{ctx};
228 const s32 fd = rp.Pop<s32>(); 228 const s32 fd = rp.Pop<s32>();
229 229
@@ -241,7 +241,7 @@ void BSD::GetPeerName(Kernel::HLERequestContext& ctx) {
241 rb.Push<u32>(static_cast<u32>(write_buffer.size())); 241 rb.Push<u32>(static_cast<u32>(write_buffer.size()));
242} 242}
243 243
244void BSD::GetSockName(Kernel::HLERequestContext& ctx) { 244void BSD::GetSockName(HLERequestContext& ctx) {
245 IPC::RequestParser rp{ctx}; 245 IPC::RequestParser rp{ctx};
246 const s32 fd = rp.Pop<s32>(); 246 const s32 fd = rp.Pop<s32>();
247 247
@@ -259,7 +259,7 @@ void BSD::GetSockName(Kernel::HLERequestContext& ctx) {
259 rb.Push<u32>(static_cast<u32>(write_buffer.size())); 259 rb.Push<u32>(static_cast<u32>(write_buffer.size()));
260} 260}
261 261
262void BSD::GetSockOpt(Kernel::HLERequestContext& ctx) { 262void BSD::GetSockOpt(HLERequestContext& ctx) {
263 IPC::RequestParser rp{ctx}; 263 IPC::RequestParser rp{ctx};
264 const s32 fd = rp.Pop<s32>(); 264 const s32 fd = rp.Pop<s32>();
265 const u32 level = rp.Pop<u32>(); 265 const u32 level = rp.Pop<u32>();
@@ -278,7 +278,7 @@ void BSD::GetSockOpt(Kernel::HLERequestContext& ctx) {
278 rb.Push<u32>(static_cast<u32>(optval.size())); 278 rb.Push<u32>(static_cast<u32>(optval.size()));
279} 279}
280 280
281void BSD::Listen(Kernel::HLERequestContext& ctx) { 281void BSD::Listen(HLERequestContext& ctx) {
282 IPC::RequestParser rp{ctx}; 282 IPC::RequestParser rp{ctx};
283 const s32 fd = rp.Pop<s32>(); 283 const s32 fd = rp.Pop<s32>();
284 const s32 backlog = rp.Pop<s32>(); 284 const s32 backlog = rp.Pop<s32>();
@@ -288,7 +288,7 @@ void BSD::Listen(Kernel::HLERequestContext& ctx) {
288 BuildErrnoResponse(ctx, ListenImpl(fd, backlog)); 288 BuildErrnoResponse(ctx, ListenImpl(fd, backlog));
289} 289}
290 290
291void BSD::Fcntl(Kernel::HLERequestContext& ctx) { 291void BSD::Fcntl(HLERequestContext& ctx) {
292 IPC::RequestParser rp{ctx}; 292 IPC::RequestParser rp{ctx};
293 const s32 fd = rp.Pop<s32>(); 293 const s32 fd = rp.Pop<s32>();
294 const s32 cmd = rp.Pop<s32>(); 294 const s32 cmd = rp.Pop<s32>();
@@ -304,7 +304,7 @@ void BSD::Fcntl(Kernel::HLERequestContext& ctx) {
304 rb.PushEnum(bsd_errno); 304 rb.PushEnum(bsd_errno);
305} 305}
306 306
307void BSD::SetSockOpt(Kernel::HLERequestContext& ctx) { 307void BSD::SetSockOpt(HLERequestContext& ctx) {
308 IPC::RequestParser rp{ctx}; 308 IPC::RequestParser rp{ctx};
309 309
310 const s32 fd = rp.Pop<s32>(); 310 const s32 fd = rp.Pop<s32>();
@@ -328,7 +328,7 @@ void BSD::SetSockOpt(Kernel::HLERequestContext& ctx) {
328 BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optlen, optval)); 328 BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optlen, optval));
329} 329}
330 330
331void BSD::Shutdown(Kernel::HLERequestContext& ctx) { 331void BSD::Shutdown(HLERequestContext& ctx) {
332 IPC::RequestParser rp{ctx}; 332 IPC::RequestParser rp{ctx};
333 333
334 const s32 fd = rp.Pop<s32>(); 334 const s32 fd = rp.Pop<s32>();
@@ -339,7 +339,7 @@ void BSD::Shutdown(Kernel::HLERequestContext& ctx) {
339 BuildErrnoResponse(ctx, ShutdownImpl(fd, how)); 339 BuildErrnoResponse(ctx, ShutdownImpl(fd, how));
340} 340}
341 341
342void BSD::Recv(Kernel::HLERequestContext& ctx) { 342void BSD::Recv(HLERequestContext& ctx) {
343 IPC::RequestParser rp{ctx}; 343 IPC::RequestParser rp{ctx};
344 344
345 const s32 fd = rp.Pop<s32>(); 345 const s32 fd = rp.Pop<s32>();
@@ -354,7 +354,7 @@ void BSD::Recv(Kernel::HLERequestContext& ctx) {
354 }); 354 });
355} 355}
356 356
357void BSD::RecvFrom(Kernel::HLERequestContext& ctx) { 357void BSD::RecvFrom(HLERequestContext& ctx) {
358 IPC::RequestParser rp{ctx}; 358 IPC::RequestParser rp{ctx};
359 359
360 const s32 fd = rp.Pop<s32>(); 360 const s32 fd = rp.Pop<s32>();
@@ -371,7 +371,7 @@ void BSD::RecvFrom(Kernel::HLERequestContext& ctx) {
371 }); 371 });
372} 372}
373 373
374void BSD::Send(Kernel::HLERequestContext& ctx) { 374void BSD::Send(HLERequestContext& ctx) {
375 IPC::RequestParser rp{ctx}; 375 IPC::RequestParser rp{ctx};
376 376
377 const s32 fd = rp.Pop<s32>(); 377 const s32 fd = rp.Pop<s32>();
@@ -386,7 +386,7 @@ void BSD::Send(Kernel::HLERequestContext& ctx) {
386 }); 386 });
387} 387}
388 388
389void BSD::SendTo(Kernel::HLERequestContext& ctx) { 389void BSD::SendTo(HLERequestContext& ctx) {
390 IPC::RequestParser rp{ctx}; 390 IPC::RequestParser rp{ctx};
391 const s32 fd = rp.Pop<s32>(); 391 const s32 fd = rp.Pop<s32>();
392 const u32 flags = rp.Pop<u32>(); 392 const u32 flags = rp.Pop<u32>();
@@ -402,7 +402,7 @@ void BSD::SendTo(Kernel::HLERequestContext& ctx) {
402 }); 402 });
403} 403}
404 404
405void BSD::Write(Kernel::HLERequestContext& ctx) { 405void BSD::Write(HLERequestContext& ctx) {
406 IPC::RequestParser rp{ctx}; 406 IPC::RequestParser rp{ctx};
407 const s32 fd = rp.Pop<s32>(); 407 const s32 fd = rp.Pop<s32>();
408 408
@@ -415,7 +415,7 @@ void BSD::Write(Kernel::HLERequestContext& ctx) {
415 }); 415 });
416} 416}
417 417
418void BSD::Read(Kernel::HLERequestContext& ctx) { 418void BSD::Read(HLERequestContext& ctx) {
419 IPC::RequestParser rp{ctx}; 419 IPC::RequestParser rp{ctx};
420 const s32 fd = rp.Pop<s32>(); 420 const s32 fd = rp.Pop<s32>();
421 421
@@ -427,7 +427,7 @@ void BSD::Read(Kernel::HLERequestContext& ctx) {
427 rb.Push<u32>(0); // bsd errno 427 rb.Push<u32>(0); // bsd errno
428} 428}
429 429
430void BSD::Close(Kernel::HLERequestContext& ctx) { 430void BSD::Close(HLERequestContext& ctx) {
431 IPC::RequestParser rp{ctx}; 431 IPC::RequestParser rp{ctx};
432 const s32 fd = rp.Pop<s32>(); 432 const s32 fd = rp.Pop<s32>();
433 433
@@ -436,7 +436,7 @@ void BSD::Close(Kernel::HLERequestContext& ctx) {
436 BuildErrnoResponse(ctx, CloseImpl(fd)); 436 BuildErrnoResponse(ctx, CloseImpl(fd));
437} 437}
438 438
439void BSD::EventFd(Kernel::HLERequestContext& ctx) { 439void BSD::EventFd(HLERequestContext& ctx) {
440 IPC::RequestParser rp{ctx}; 440 IPC::RequestParser rp{ctx};
441 const u64 initval = rp.Pop<u64>(); 441 const u64 initval = rp.Pop<u64>();
442 const u32 flags = rp.Pop<u32>(); 442 const u32 flags = rp.Pop<u32>();
@@ -447,7 +447,7 @@ void BSD::EventFd(Kernel::HLERequestContext& ctx) {
447} 447}
448 448
449template <typename Work> 449template <typename Work>
450void BSD::ExecuteWork(Kernel::HLERequestContext& ctx, Work work) { 450void BSD::ExecuteWork(HLERequestContext& ctx, Work work) {
451 work.Execute(this); 451 work.Execute(this);
452 work.Response(ctx); 452 work.Response(ctx);
453} 453}
@@ -862,7 +862,7 @@ bool BSD::IsFileDescriptorValid(s32 fd) const noexcept {
862 return true; 862 return true;
863} 863}
864 864
865void BSD::BuildErrnoResponse(Kernel::HLERequestContext& ctx, Errno bsd_errno) const noexcept { 865void BSD::BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept {
866 IPC::ResponseBuilder rb{ctx, 4}; 866 IPC::ResponseBuilder rb{ctx, 4};
867 867
868 rb.Push(ResultSuccess); 868 rb.Push(ResultSuccess);
@@ -881,8 +881,7 @@ void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
881} 881}
882 882
883BSD::BSD(Core::System& system_, const char* name) 883BSD::BSD(Core::System& system_, const char* name)
884 : ServiceFramework{system_, name, ServiceThreadType::CreateNew}, room_network{ 884 : ServiceFramework{system_, name}, room_network{system_.GetRoomNetwork()} {
885 system_.GetRoomNetwork()} {
886 // clang-format off 885 // clang-format off
887 static const FunctionInfo functions[] = { 886 static const FunctionInfo functions[] = {
888 {0, &BSD::RegisterClient, "RegisterClient"}, 887 {0, &BSD::RegisterClient, "RegisterClient"},
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h
index 56bb3f8b1..30ae9c140 100644
--- a/src/core/hle/service/sockets/bsd.h
+++ b/src/core/hle/service/sockets/bsd.h
@@ -41,7 +41,7 @@ private:
41 41
42 struct PollWork { 42 struct PollWork {
43 void Execute(BSD* bsd); 43 void Execute(BSD* bsd);
44 void Response(Kernel::HLERequestContext& ctx); 44 void Response(HLERequestContext& ctx);
45 45
46 s32 nfds; 46 s32 nfds;
47 s32 timeout; 47 s32 timeout;
@@ -53,7 +53,7 @@ private:
53 53
54 struct AcceptWork { 54 struct AcceptWork {
55 void Execute(BSD* bsd); 55 void Execute(BSD* bsd);
56 void Response(Kernel::HLERequestContext& ctx); 56 void Response(HLERequestContext& ctx);
57 57
58 s32 fd; 58 s32 fd;
59 std::vector<u8> write_buffer; 59 std::vector<u8> write_buffer;
@@ -63,7 +63,7 @@ private:
63 63
64 struct ConnectWork { 64 struct ConnectWork {
65 void Execute(BSD* bsd); 65 void Execute(BSD* bsd);
66 void Response(Kernel::HLERequestContext& ctx); 66 void Response(HLERequestContext& ctx);
67 67
68 s32 fd; 68 s32 fd;
69 std::span<const u8> addr; 69 std::span<const u8> addr;
@@ -72,7 +72,7 @@ private:
72 72
73 struct RecvWork { 73 struct RecvWork {
74 void Execute(BSD* bsd); 74 void Execute(BSD* bsd);
75 void Response(Kernel::HLERequestContext& ctx); 75 void Response(HLERequestContext& ctx);
76 76
77 s32 fd; 77 s32 fd;
78 u32 flags; 78 u32 flags;
@@ -83,7 +83,7 @@ private:
83 83
84 struct RecvFromWork { 84 struct RecvFromWork {
85 void Execute(BSD* bsd); 85 void Execute(BSD* bsd);
86 void Response(Kernel::HLERequestContext& ctx); 86 void Response(HLERequestContext& ctx);
87 87
88 s32 fd; 88 s32 fd;
89 u32 flags; 89 u32 flags;
@@ -95,7 +95,7 @@ private:
95 95
96 struct SendWork { 96 struct SendWork {
97 void Execute(BSD* bsd); 97 void Execute(BSD* bsd);
98 void Response(Kernel::HLERequestContext& ctx); 98 void Response(HLERequestContext& ctx);
99 99
100 s32 fd; 100 s32 fd;
101 u32 flags; 101 u32 flags;
@@ -106,7 +106,7 @@ private:
106 106
107 struct SendToWork { 107 struct SendToWork {
108 void Execute(BSD* bsd); 108 void Execute(BSD* bsd);
109 void Response(Kernel::HLERequestContext& ctx); 109 void Response(HLERequestContext& ctx);
110 110
111 s32 fd; 111 s32 fd;
112 u32 flags; 112 u32 flags;
@@ -116,32 +116,32 @@ private:
116 Errno bsd_errno{}; 116 Errno bsd_errno{};
117 }; 117 };
118 118
119 void RegisterClient(Kernel::HLERequestContext& ctx); 119 void RegisterClient(HLERequestContext& ctx);
120 void StartMonitoring(Kernel::HLERequestContext& ctx); 120 void StartMonitoring(HLERequestContext& ctx);
121 void Socket(Kernel::HLERequestContext& ctx); 121 void Socket(HLERequestContext& ctx);
122 void Select(Kernel::HLERequestContext& ctx); 122 void Select(HLERequestContext& ctx);
123 void Poll(Kernel::HLERequestContext& ctx); 123 void Poll(HLERequestContext& ctx);
124 void Accept(Kernel::HLERequestContext& ctx); 124 void Accept(HLERequestContext& ctx);
125 void Bind(Kernel::HLERequestContext& ctx); 125 void Bind(HLERequestContext& ctx);
126 void Connect(Kernel::HLERequestContext& ctx); 126 void Connect(HLERequestContext& ctx);
127 void GetPeerName(Kernel::HLERequestContext& ctx); 127 void GetPeerName(HLERequestContext& ctx);
128 void GetSockName(Kernel::HLERequestContext& ctx); 128 void GetSockName(HLERequestContext& ctx);
129 void GetSockOpt(Kernel::HLERequestContext& ctx); 129 void GetSockOpt(HLERequestContext& ctx);
130 void Listen(Kernel::HLERequestContext& ctx); 130 void Listen(HLERequestContext& ctx);
131 void Fcntl(Kernel::HLERequestContext& ctx); 131 void Fcntl(HLERequestContext& ctx);
132 void SetSockOpt(Kernel::HLERequestContext& ctx); 132 void SetSockOpt(HLERequestContext& ctx);
133 void Shutdown(Kernel::HLERequestContext& ctx); 133 void Shutdown(HLERequestContext& ctx);
134 void Recv(Kernel::HLERequestContext& ctx); 134 void Recv(HLERequestContext& ctx);
135 void RecvFrom(Kernel::HLERequestContext& ctx); 135 void RecvFrom(HLERequestContext& ctx);
136 void Send(Kernel::HLERequestContext& ctx); 136 void Send(HLERequestContext& ctx);
137 void SendTo(Kernel::HLERequestContext& ctx); 137 void SendTo(HLERequestContext& ctx);
138 void Write(Kernel::HLERequestContext& ctx); 138 void Write(HLERequestContext& ctx);
139 void Read(Kernel::HLERequestContext& ctx); 139 void Read(HLERequestContext& ctx);
140 void Close(Kernel::HLERequestContext& ctx); 140 void Close(HLERequestContext& ctx);
141 void EventFd(Kernel::HLERequestContext& ctx); 141 void EventFd(HLERequestContext& ctx);
142 142
143 template <typename Work> 143 template <typename Work>
144 void ExecuteWork(Kernel::HLERequestContext& ctx, Work work); 144 void ExecuteWork(HLERequestContext& ctx, Work work);
145 145
146 std::pair<s32, Errno> SocketImpl(Domain domain, Type type, Protocol protocol); 146 std::pair<s32, Errno> SocketImpl(Domain domain, Type type, Protocol protocol);
147 std::pair<s32, Errno> PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer, 147 std::pair<s32, Errno> PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
@@ -166,7 +166,7 @@ private:
166 s32 FindFreeFileDescriptorHandle() noexcept; 166 s32 FindFreeFileDescriptorHandle() noexcept;
167 bool IsFileDescriptorValid(s32 fd) const noexcept; 167 bool IsFileDescriptorValid(s32 fd) const noexcept;
168 168
169 void BuildErrnoResponse(Kernel::HLERequestContext& ctx, Errno bsd_errno) const noexcept; 169 void BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept;
170 170
171 std::array<std::optional<FileDescriptor>, MAX_FD> file_descriptors; 171 std::array<std::optional<FileDescriptor>, MAX_FD> file_descriptors;
172 172
diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp
index e96eda7f3..132dd5797 100644
--- a/src/core/hle/service/sockets/sfdnsres.cpp
+++ b/src/core/hle/service/sockets/sfdnsres.cpp
@@ -8,7 +8,7 @@
8#include "common/string_util.h" 8#include "common/string_util.h"
9#include "common/swap.h" 9#include "common/swap.h"
10#include "core/core.h" 10#include "core/core.h"
11#include "core/hle/ipc_helpers.h" 11#include "core/hle/service/ipc_helpers.h"
12#include "core/hle/service/sockets/sfdnsres.h" 12#include "core/hle/service/sockets/sfdnsres.h"
13#include "core/memory.h" 13#include "core/memory.h"
14 14
@@ -185,7 +185,7 @@ static std::vector<u8> SerializeAddrInfo(const addrinfo* addrinfo, s32 result_co
185 return data; 185 return data;
186} 186}
187 187
188static std::pair<u32, s32> GetAddrInfoRequestImpl(Kernel::HLERequestContext& ctx) { 188static std::pair<u32, s32> GetAddrInfoRequestImpl(HLERequestContext& ctx) {
189 struct Parameters { 189 struct Parameters {
190 u8 use_nsd_resolve; 190 u8 use_nsd_resolve;
191 u32 unknown; 191 u32 unknown;
@@ -221,7 +221,7 @@ static std::pair<u32, s32> GetAddrInfoRequestImpl(Kernel::HLERequestContext& ctx
221 return std::make_pair(data_size, result_code); 221 return std::make_pair(data_size, result_code);
222} 222}
223 223
224void SFDNSRES::GetAddrInfoRequest(Kernel::HLERequestContext& ctx) { 224void SFDNSRES::GetAddrInfoRequest(HLERequestContext& ctx) {
225 auto [data_size, result_code] = GetAddrInfoRequestImpl(ctx); 225 auto [data_size, result_code] = GetAddrInfoRequestImpl(ctx);
226 226
227 IPC::ResponseBuilder rb{ctx, 4}; 227 IPC::ResponseBuilder rb{ctx, 4};
@@ -231,7 +231,7 @@ void SFDNSRES::GetAddrInfoRequest(Kernel::HLERequestContext& ctx) {
231 rb.Push(data_size); // serialized size 231 rb.Push(data_size); // serialized size
232} 232}
233 233
234void SFDNSRES::GetAddrInfoRequestWithOptions(Kernel::HLERequestContext& ctx) { 234void SFDNSRES::GetAddrInfoRequestWithOptions(HLERequestContext& ctx) {
235 // Additional options are ignored 235 // Additional options are ignored
236 auto [data_size, result_code] = GetAddrInfoRequestImpl(ctx); 236 auto [data_size, result_code] = GetAddrInfoRequestImpl(ctx);
237 237
diff --git a/src/core/hle/service/sockets/sfdnsres.h b/src/core/hle/service/sockets/sfdnsres.h
index 96018ea77..18e3cd60c 100644
--- a/src/core/hle/service/sockets/sfdnsres.h
+++ b/src/core/hle/service/sockets/sfdnsres.h
@@ -17,8 +17,8 @@ public:
17 ~SFDNSRES() override; 17 ~SFDNSRES() override;
18 18
19private: 19private:
20 void GetAddrInfoRequest(Kernel::HLERequestContext& ctx); 20 void GetAddrInfoRequest(HLERequestContext& ctx);
21 void GetAddrInfoRequestWithOptions(Kernel::HLERequestContext& ctx); 21 void GetAddrInfoRequestWithOptions(HLERequestContext& ctx);
22}; 22};
23 23
24} // namespace Service::Sockets 24} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/sockets.cpp b/src/core/hle/service/sockets/sockets.cpp
index b191b5cf5..676d24e03 100644
--- a/src/core/hle/service/sockets/sockets.cpp
+++ b/src/core/hle/service/sockets/sockets.cpp
@@ -1,6 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/server_manager.h"
4#include "core/hle/service/sockets/bsd.h" 5#include "core/hle/service/sockets/bsd.h"
5#include "core/hle/service/sockets/nsd.h" 6#include "core/hle/service/sockets/nsd.h"
6#include "core/hle/service/sockets/sfdnsres.h" 7#include "core/hle/service/sockets/sfdnsres.h"
@@ -8,15 +9,17 @@
8 9
9namespace Service::Sockets { 10namespace Service::Sockets {
10 11
11void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 12void LoopProcess(Core::System& system) {
12 std::make_shared<BSD>(system, "bsd:s")->InstallAsService(service_manager); 13 auto server_manager = std::make_unique<ServerManager>(system);
13 std::make_shared<BSD>(system, "bsd:u")->InstallAsService(service_manager);
14 std::make_shared<BSDCFG>(system)->InstallAsService(service_manager);
15 14
16 std::make_shared<NSD>(system, "nsd:a")->InstallAsService(service_manager); 15 server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD>(system, "bsd:s"));
17 std::make_shared<NSD>(system, "nsd:u")->InstallAsService(service_manager); 16 server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD>(system, "bsd:u"));
18 17 server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system));
19 std::make_shared<SFDNSRES>(system)->InstallAsService(service_manager); 18 server_manager->RegisterNamedService("nsd:a", std::make_shared<NSD>(system, "nsd:a"));
19 server_manager->RegisterNamedService("nsd:u", std::make_shared<NSD>(system, "nsd:u"));
20 server_manager->RegisterNamedService("sfdnsres", std::make_shared<SFDNSRES>(system));
21 server_manager->StartAdditionalHostThreads("bsdsocket", 2);
22 ServerManager::RunServer(std::move(server_manager));
20} 23}
21 24
22} // namespace Service::Sockets 25} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/sockets.h b/src/core/hle/service/sockets/sockets.h
index 9840c11f9..acd2dae7b 100644
--- a/src/core/hle/service/sockets/sockets.h
+++ b/src/core/hle/service/sockets/sockets.h
@@ -10,10 +10,6 @@ namespace Core {
10class System; 10class System;
11} 11}
12 12
13namespace Service::SM {
14class ServiceManager;
15}
16
17namespace Service::Sockets { 13namespace Service::Sockets {
18 14
19enum class Errno : u32 { 15enum class Errno : u32 {
@@ -99,7 +95,6 @@ struct Linger {
99 u32 linger; 95 u32 linger;
100}; 96};
101 97
102/// Registers all Sockets services with the specified service manager. 98void LoopProcess(Core::System& system);
103void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
104 99
105} // namespace Service::Sockets 100} // namespace Service::Sockets
diff --git a/src/core/hle/service/spl/spl_module.cpp b/src/core/hle/service/spl/spl_module.cpp
index 64eae1ebf..0227d4393 100644
--- a/src/core/hle/service/spl/spl_module.cpp
+++ b/src/core/hle/service/spl/spl_module.cpp
@@ -8,7 +8,8 @@
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "common/settings.h" 9#include "common/settings.h"
10#include "core/hle/api_version.h" 10#include "core/hle/api_version.h"
11#include "core/hle/ipc_helpers.h" 11#include "core/hle/service/ipc_helpers.h"
12#include "core/hle/service/server_manager.h"
12#include "core/hle/service/spl/csrng.h" 13#include "core/hle/service/spl/csrng.h"
13#include "core/hle/service/spl/spl.h" 14#include "core/hle/service/spl/spl.h"
14#include "core/hle/service/spl/spl_module.h" 15#include "core/hle/service/spl/spl_module.h"
@@ -22,7 +23,7 @@ Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> modu
22 23
23Module::Interface::~Interface() = default; 24Module::Interface::~Interface() = default;
24 25
25void Module::Interface::GetConfig(Kernel::HLERequestContext& ctx) { 26void Module::Interface::GetConfig(HLERequestContext& ctx) {
26 IPC::RequestParser rp{ctx}; 27 IPC::RequestParser rp{ctx};
27 const auto config_item = rp.PopEnum<ConfigItem>(); 28 const auto config_item = rp.PopEnum<ConfigItem>();
28 29
@@ -47,21 +48,21 @@ void Module::Interface::GetConfig(Kernel::HLERequestContext& ctx) {
47 rb.Push(*smc_result); 48 rb.Push(*smc_result);
48} 49}
49 50
50void Module::Interface::ModularExponentiate(Kernel::HLERequestContext& ctx) { 51void Module::Interface::ModularExponentiate(HLERequestContext& ctx) {
51 UNIMPLEMENTED_MSG("ModularExponentiate is not implemented!"); 52 UNIMPLEMENTED_MSG("ModularExponentiate is not implemented!");
52 53
53 IPC::ResponseBuilder rb{ctx, 2}; 54 IPC::ResponseBuilder rb{ctx, 2};
54 rb.Push(ResultSecureMonitorNotImplemented); 55 rb.Push(ResultSecureMonitorNotImplemented);
55} 56}
56 57
57void Module::Interface::SetConfig(Kernel::HLERequestContext& ctx) { 58void Module::Interface::SetConfig(HLERequestContext& ctx) {
58 UNIMPLEMENTED_MSG("SetConfig is not implemented!"); 59 UNIMPLEMENTED_MSG("SetConfig is not implemented!");
59 60
60 IPC::ResponseBuilder rb{ctx, 2}; 61 IPC::ResponseBuilder rb{ctx, 2};
61 rb.Push(ResultSecureMonitorNotImplemented); 62 rb.Push(ResultSecureMonitorNotImplemented);
62} 63}
63 64
64void Module::Interface::GenerateRandomBytes(Kernel::HLERequestContext& ctx) { 65void Module::Interface::GenerateRandomBytes(HLERequestContext& ctx) {
65 LOG_DEBUG(Service_SPL, "called"); 66 LOG_DEBUG(Service_SPL, "called");
66 67
67 const std::size_t size = ctx.GetWriteBufferSize(); 68 const std::size_t size = ctx.GetWriteBufferSize();
@@ -76,21 +77,21 @@ void Module::Interface::GenerateRandomBytes(Kernel::HLERequestContext& ctx) {
76 rb.Push(ResultSuccess); 77 rb.Push(ResultSuccess);
77} 78}
78 79
79void Module::Interface::IsDevelopment(Kernel::HLERequestContext& ctx) { 80void Module::Interface::IsDevelopment(HLERequestContext& ctx) {
80 UNIMPLEMENTED_MSG("IsDevelopment is not implemented!"); 81 UNIMPLEMENTED_MSG("IsDevelopment is not implemented!");
81 82
82 IPC::ResponseBuilder rb{ctx, 2}; 83 IPC::ResponseBuilder rb{ctx, 2};
83 rb.Push(ResultSecureMonitorNotImplemented); 84 rb.Push(ResultSecureMonitorNotImplemented);
84} 85}
85 86
86void Module::Interface::SetBootReason(Kernel::HLERequestContext& ctx) { 87void Module::Interface::SetBootReason(HLERequestContext& ctx) {
87 UNIMPLEMENTED_MSG("SetBootReason is not implemented!"); 88 UNIMPLEMENTED_MSG("SetBootReason is not implemented!");
88 89
89 IPC::ResponseBuilder rb{ctx, 2}; 90 IPC::ResponseBuilder rb{ctx, 2};
90 rb.Push(ResultSecureMonitorNotImplemented); 91 rb.Push(ResultSecureMonitorNotImplemented);
91} 92}
92 93
93void Module::Interface::GetBootReason(Kernel::HLERequestContext& ctx) { 94void Module::Interface::GetBootReason(HLERequestContext& ctx) {
94 UNIMPLEMENTED_MSG("GetBootReason is not implemented!"); 95 UNIMPLEMENTED_MSG("GetBootReason is not implemented!");
95 96
96 IPC::ResponseBuilder rb{ctx, 2}; 97 IPC::ResponseBuilder rb{ctx, 2};
@@ -158,15 +159,18 @@ ResultVal<u64> Module::Interface::GetConfigImpl(ConfigItem config_item) const {
158 } 159 }
159} 160}
160 161
161void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 162void LoopProcess(Core::System& system) {
163 auto server_manager = std::make_unique<ServerManager>(system);
162 auto module = std::make_shared<Module>(); 164 auto module = std::make_shared<Module>();
163 std::make_shared<CSRNG>(system, module)->InstallAsService(service_manager); 165
164 std::make_shared<SPL>(system, module)->InstallAsService(service_manager); 166 server_manager->RegisterNamedService("csrng", std::make_shared<CSRNG>(system, module));
165 std::make_shared<SPL_MIG>(system, module)->InstallAsService(service_manager); 167 server_manager->RegisterNamedService("spl", std::make_shared<SPL>(system, module));
166 std::make_shared<SPL_FS>(system, module)->InstallAsService(service_manager); 168 server_manager->RegisterNamedService("spl:mig", std::make_shared<SPL_MIG>(system, module));
167 std::make_shared<SPL_SSL>(system, module)->InstallAsService(service_manager); 169 server_manager->RegisterNamedService("spl:fs", std::make_shared<SPL_FS>(system, module));
168 std::make_shared<SPL_ES>(system, module)->InstallAsService(service_manager); 170 server_manager->RegisterNamedService("spl:ssl", std::make_shared<SPL_SSL>(system, module));
169 std::make_shared<SPL_MANU>(system, module)->InstallAsService(service_manager); 171 server_manager->RegisterNamedService("spl:es", std::make_shared<SPL_ES>(system, module));
172 server_manager->RegisterNamedService("spl:manu", std::make_shared<SPL_MANU>(system, module));
173 ServerManager::RunServer(std::move(server_manager));
170} 174}
171 175
172} // namespace Service::SPL 176} // namespace Service::SPL
diff --git a/src/core/hle/service/spl/spl_module.h b/src/core/hle/service/spl/spl_module.h
index 4c9a3c618..e074e115d 100644
--- a/src/core/hle/service/spl/spl_module.h
+++ b/src/core/hle/service/spl/spl_module.h
@@ -23,13 +23,13 @@ public:
23 ~Interface() override; 23 ~Interface() override;
24 24
25 // General 25 // General
26 void GetConfig(Kernel::HLERequestContext& ctx); 26 void GetConfig(HLERequestContext& ctx);
27 void ModularExponentiate(Kernel::HLERequestContext& ctx); 27 void ModularExponentiate(HLERequestContext& ctx);
28 void SetConfig(Kernel::HLERequestContext& ctx); 28 void SetConfig(HLERequestContext& ctx);
29 void GenerateRandomBytes(Kernel::HLERequestContext& ctx); 29 void GenerateRandomBytes(HLERequestContext& ctx);
30 void IsDevelopment(Kernel::HLERequestContext& ctx); 30 void IsDevelopment(HLERequestContext& ctx);
31 void SetBootReason(Kernel::HLERequestContext& ctx); 31 void SetBootReason(HLERequestContext& ctx);
32 void GetBootReason(Kernel::HLERequestContext& ctx); 32 void GetBootReason(HLERequestContext& ctx);
33 33
34 protected: 34 protected:
35 std::shared_ptr<Module> module; 35 std::shared_ptr<Module> module;
@@ -41,7 +41,6 @@ public:
41 }; 41 };
42}; 42};
43 43
44/// Registers all SPL services with the specified service manager. 44void LoopProcess(Core::System& system);
45void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
46 45
47} // namespace Service::SPL 46} // namespace Service::SPL
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp
index 015208593..2b99dd7ac 100644
--- a/src/core/hle/service/ssl/ssl.cpp
+++ b/src/core/hle/service/ssl/ssl.cpp
@@ -1,21 +1,43 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/ipc_helpers.h" 4#include "core/hle/service/ipc_helpers.h"
5#include "core/hle/service/server_manager.h"
5#include "core/hle/service/service.h" 6#include "core/hle/service/service.h"
6#include "core/hle/service/sm/sm.h"
7#include "core/hle/service/ssl/ssl.h" 7#include "core/hle/service/ssl/ssl.h"
8 8
9namespace Service::SSL { 9namespace Service::SSL {
10 10
11// This is nn::ssl::sf::CertificateFormat
11enum class CertificateFormat : u32 { 12enum class CertificateFormat : u32 {
12 Pem = 1, 13 Pem = 1,
13 Der = 2, 14 Der = 2,
14}; 15};
15 16
17// This is nn::ssl::sf::ContextOption
18enum class ContextOption : u32 {
19 None = 0,
20 CrlImportDateCheckEnable = 1,
21};
22
23// This is nn::ssl::sf::SslVersion
24struct SslVersion {
25 union {
26 u32 raw{};
27
28 BitField<0, 1, u32> tls_auto;
29 BitField<3, 1, u32> tls_v10;
30 BitField<4, 1, u32> tls_v11;
31 BitField<5, 1, u32> tls_v12;
32 BitField<6, 1, u32> tls_v13;
33 BitField<24, 7, u32> api_version;
34 };
35};
36
16class ISslConnection final : public ServiceFramework<ISslConnection> { 37class ISslConnection final : public ServiceFramework<ISslConnection> {
17public: 38public:
18 explicit ISslConnection(Core::System& system_) : ServiceFramework{system_, "ISslConnection"} { 39 explicit ISslConnection(Core::System& system_, SslVersion version)
40 : ServiceFramework{system_, "ISslConnection"}, ssl_version{version} {
19 // clang-format off 41 // clang-format off
20 static const FunctionInfo functions[] = { 42 static const FunctionInfo functions[] = {
21 {0, nullptr, "SetSocketDescriptor"}, 43 {0, nullptr, "SetSocketDescriptor"},
@@ -59,11 +81,15 @@ public:
59 81
60 RegisterHandlers(functions); 82 RegisterHandlers(functions);
61 } 83 }
84
85private:
86 SslVersion ssl_version;
62}; 87};
63 88
64class ISslContext final : public ServiceFramework<ISslContext> { 89class ISslContext final : public ServiceFramework<ISslContext> {
65public: 90public:
66 explicit ISslContext(Core::System& system_) : ServiceFramework{system_, "ISslContext"} { 91 explicit ISslContext(Core::System& system_, SslVersion version)
92 : ServiceFramework{system_, "ISslContext"}, ssl_version{version} {
67 static const FunctionInfo functions[] = { 93 static const FunctionInfo functions[] = {
68 {0, &ISslContext::SetOption, "SetOption"}, 94 {0, &ISslContext::SetOption, "SetOption"},
69 {1, nullptr, "GetOption"}, 95 {1, nullptr, "GetOption"},
@@ -84,31 +110,34 @@ public:
84 } 110 }
85 111
86private: 112private:
87 void SetOption(Kernel::HLERequestContext& ctx) { 113 SslVersion ssl_version;
114
115 void SetOption(HLERequestContext& ctx) {
88 struct Parameters { 116 struct Parameters {
89 u8 enable; 117 ContextOption option;
90 u32 option; 118 s32 value;
91 }; 119 };
120 static_assert(sizeof(Parameters) == 0x8, "Parameters is an invalid size");
92 121
93 IPC::RequestParser rp{ctx}; 122 IPC::RequestParser rp{ctx};
94 const auto parameters = rp.PopRaw<Parameters>(); 123 const auto parameters = rp.PopRaw<Parameters>();
95 124
96 LOG_WARNING(Service_SSL, "(STUBBED) called. enable={}, option={}", parameters.enable, 125 LOG_WARNING(Service_SSL, "(STUBBED) called. option={}, value={}", parameters.option,
97 parameters.option); 126 parameters.value);
98 127
99 IPC::ResponseBuilder rb{ctx, 2}; 128 IPC::ResponseBuilder rb{ctx, 2};
100 rb.Push(ResultSuccess); 129 rb.Push(ResultSuccess);
101 } 130 }
102 131
103 void CreateConnection(Kernel::HLERequestContext& ctx) { 132 void CreateConnection(HLERequestContext& ctx) {
104 LOG_WARNING(Service_SSL, "(STUBBED) called"); 133 LOG_WARNING(Service_SSL, "(STUBBED) called");
105 134
106 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 135 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
107 rb.Push(ResultSuccess); 136 rb.Push(ResultSuccess);
108 rb.PushIpcInterface<ISslConnection>(system); 137 rb.PushIpcInterface<ISslConnection>(system, ssl_version);
109 } 138 }
110 139
111 void ImportServerPki(Kernel::HLERequestContext& ctx) { 140 void ImportServerPki(HLERequestContext& ctx) {
112 IPC::RequestParser rp{ctx}; 141 IPC::RequestParser rp{ctx};
113 const auto certificate_format = rp.PopEnum<CertificateFormat>(); 142 const auto certificate_format = rp.PopEnum<CertificateFormat>();
114 [[maybe_unused]] const auto pkcs_12_certificates = ctx.ReadBuffer(0); 143 [[maybe_unused]] const auto pkcs_12_certificates = ctx.ReadBuffer(0);
@@ -122,7 +151,7 @@ private:
122 rb.Push(server_id); 151 rb.Push(server_id);
123 } 152 }
124 153
125 void ImportClientPki(Kernel::HLERequestContext& ctx) { 154 void ImportClientPki(HLERequestContext& ctx) {
126 [[maybe_unused]] const auto pkcs_12_certificate = ctx.ReadBuffer(0); 155 [[maybe_unused]] const auto pkcs_12_certificate = ctx.ReadBuffer(0);
127 [[maybe_unused]] const auto ascii_password = [&ctx] { 156 [[maybe_unused]] const auto ascii_password = [&ctx] {
128 if (ctx.CanReadBuffer(1)) { 157 if (ctx.CanReadBuffer(1)) {
@@ -142,20 +171,21 @@ private:
142 } 171 }
143}; 172};
144 173
145class SSL final : public ServiceFramework<SSL> { 174class ISslService final : public ServiceFramework<ISslService> {
146public: 175public:
147 explicit SSL(Core::System& system_) : ServiceFramework{system_, "ssl"} { 176 explicit ISslService(Core::System& system_) : ServiceFramework{system_, "ssl"} {
148 // clang-format off 177 // clang-format off
149 static const FunctionInfo functions[] = { 178 static const FunctionInfo functions[] = {
150 {0, &SSL::CreateContext, "CreateContext"}, 179 {0, &ISslService::CreateContext, "CreateContext"},
151 {1, nullptr, "GetContextCount"}, 180 {1, nullptr, "GetContextCount"},
152 {2, nullptr, "GetCertificates"}, 181 {2, nullptr, "GetCertificates"},
153 {3, nullptr, "GetCertificateBufSize"}, 182 {3, nullptr, "GetCertificateBufSize"},
154 {4, nullptr, "DebugIoctl"}, 183 {4, nullptr, "DebugIoctl"},
155 {5, &SSL::SetInterfaceVersion, "SetInterfaceVersion"}, 184 {5, &ISslService::SetInterfaceVersion, "SetInterfaceVersion"},
156 {6, nullptr, "FlushSessionCache"}, 185 {6, nullptr, "FlushSessionCache"},
157 {7, nullptr, "SetDebugOption"}, 186 {7, nullptr, "SetDebugOption"},
158 {8, nullptr, "GetDebugOption"}, 187 {8, nullptr, "GetDebugOption"},
188 {8, nullptr, "ClearTls12FallbackFlag"},
159 }; 189 };
160 // clang-format on 190 // clang-format on
161 191
@@ -163,28 +193,41 @@ public:
163 } 193 }
164 194
165private: 195private:
166 u32 ssl_version{}; 196 void CreateContext(HLERequestContext& ctx) {
167 void CreateContext(Kernel::HLERequestContext& ctx) { 197 struct Parameters {
168 LOG_WARNING(Service_SSL, "(STUBBED) called"); 198 SslVersion ssl_version;
199 INSERT_PADDING_BYTES(0x4);
200 u64 pid_placeholder;
201 };
202 static_assert(sizeof(Parameters) == 0x10, "Parameters is an invalid size");
203
204 IPC::RequestParser rp{ctx};
205 const auto parameters = rp.PopRaw<Parameters>();
206
207 LOG_WARNING(Service_SSL, "(STUBBED) called, api_version={}, pid_placeholder={}",
208 parameters.ssl_version.api_version, parameters.pid_placeholder);
169 209
170 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 210 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
171 rb.Push(ResultSuccess); 211 rb.Push(ResultSuccess);
172 rb.PushIpcInterface<ISslContext>(system); 212 rb.PushIpcInterface<ISslContext>(system, parameters.ssl_version);
173 } 213 }
174 214
175 void SetInterfaceVersion(Kernel::HLERequestContext& ctx) { 215 void SetInterfaceVersion(HLERequestContext& ctx) {
176 LOG_DEBUG(Service_SSL, "called");
177
178 IPC::RequestParser rp{ctx}; 216 IPC::RequestParser rp{ctx};
179 ssl_version = rp.Pop<u32>(); 217 u32 ssl_version = rp.Pop<u32>();
218
219 LOG_DEBUG(Service_SSL, "called, ssl_version={}", ssl_version);
180 220
181 IPC::ResponseBuilder rb{ctx, 2}; 221 IPC::ResponseBuilder rb{ctx, 2};
182 rb.Push(ResultSuccess); 222 rb.Push(ResultSuccess);
183 } 223 }
184}; 224};
185 225
186void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 226void LoopProcess(Core::System& system) {
187 std::make_shared<SSL>(system)->InstallAsService(service_manager); 227 auto server_manager = std::make_unique<ServerManager>(system);
228
229 server_manager->RegisterNamedService("ssl", std::make_shared<ISslService>(system));
230 ServerManager::RunServer(std::move(server_manager));
188} 231}
189 232
190} // namespace Service::SSL 233} // namespace Service::SSL
diff --git a/src/core/hle/service/ssl/ssl.h b/src/core/hle/service/ssl/ssl.h
index 27b38a003..f6e21bbb3 100644
--- a/src/core/hle/service/ssl/ssl.h
+++ b/src/core/hle/service/ssl/ssl.h
@@ -7,13 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::SSL { 10namespace Service::SSL {
15 11
16/// Registers all SSL services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::SSL 14} // namespace Service::SSL
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index f77cdbb43..868be60c5 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -5,8 +5,9 @@
5#include "core/core.h" 5#include "core/core.h"
6#include "core/core_timing.h" 6#include "core/core_timing.h"
7#include "core/hardware_properties.h" 7#include "core/hardware_properties.h"
8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/kernel.h"
9#include "core/hle/service/ipc_helpers.h"
10#include "core/hle/service/server_manager.h"
10#include "core/hle/service/time/time.h" 11#include "core/hle/service/time/time.h"
11#include "core/hle/service/time/time_interface.h" 12#include "core/hle/service/time/time_interface.h"
12#include "core/hle/service/time/time_manager.h" 13#include "core/hle/service/time/time_manager.h"
@@ -33,7 +34,7 @@ public:
33 } 34 }
34 35
35private: 36private:
36 void GetCurrentTime(Kernel::HLERequestContext& ctx) { 37 void GetCurrentTime(HLERequestContext& ctx) {
37 LOG_DEBUG(Service_Time, "called"); 38 LOG_DEBUG(Service_Time, "called");
38 39
39 if (!clock_core.IsInitialized()) { 40 if (!clock_core.IsInitialized()) {
@@ -54,7 +55,7 @@ private:
54 rb.Push<s64>(posix_time); 55 rb.Push<s64>(posix_time);
55 } 56 }
56 57
57 void GetSystemClockContext(Kernel::HLERequestContext& ctx) { 58 void GetSystemClockContext(HLERequestContext& ctx) {
58 LOG_DEBUG(Service_Time, "called"); 59 LOG_DEBUG(Service_Time, "called");
59 60
60 if (!clock_core.IsInitialized()) { 61 if (!clock_core.IsInitialized()) {
@@ -97,7 +98,7 @@ public:
97 } 98 }
98 99
99private: 100private:
100 void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) { 101 void GetCurrentTimePoint(HLERequestContext& ctx) {
101 LOG_DEBUG(Service_Time, "called"); 102 LOG_DEBUG(Service_Time, "called");
102 103
103 if (!clock_core.IsInitialized()) { 104 if (!clock_core.IsInitialized()) {
@@ -177,7 +178,7 @@ Result Module::Interface::GetClockSnapshotFromSystemClockContextInternal(
177 return ResultSuccess; 178 return ResultSuccess;
178} 179}
179 180
180void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) { 181void Module::Interface::GetStandardUserSystemClock(HLERequestContext& ctx) {
181 LOG_DEBUG(Service_Time, "called"); 182 LOG_DEBUG(Service_Time, "called");
182 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 183 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
183 rb.Push(ResultSuccess); 184 rb.Push(ResultSuccess);
@@ -185,7 +186,7 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct
185 system); 186 system);
186} 187}
187 188
188void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) { 189void Module::Interface::GetStandardNetworkSystemClock(HLERequestContext& ctx) {
189 LOG_DEBUG(Service_Time, "called"); 190 LOG_DEBUG(Service_Time, "called");
190 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 191 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
191 rb.Push(ResultSuccess); 192 rb.Push(ResultSuccess);
@@ -193,14 +194,14 @@ void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext&
193 system); 194 system);
194} 195}
195 196
196void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { 197void Module::Interface::GetStandardSteadyClock(HLERequestContext& ctx) {
197 LOG_DEBUG(Service_Time, "called"); 198 LOG_DEBUG(Service_Time, "called");
198 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 199 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
199 rb.Push(ResultSuccess); 200 rb.Push(ResultSuccess);
200 rb.PushIpcInterface<ISteadyClock>(system.GetTimeManager().GetStandardSteadyClockCore(), system); 201 rb.PushIpcInterface<ISteadyClock>(system.GetTimeManager().GetStandardSteadyClockCore(), system);
201} 202}
202 203
203void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { 204void Module::Interface::GetTimeZoneService(HLERequestContext& ctx) {
204 LOG_DEBUG(Service_Time, "called"); 205 LOG_DEBUG(Service_Time, "called");
205 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 206 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
206 rb.Push(ResultSuccess); 207 rb.Push(ResultSuccess);
@@ -208,7 +209,7 @@ void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
208 system.GetTimeManager().GetTimeZoneContentManager()); 209 system.GetTimeManager().GetTimeZoneContentManager());
209} 210}
210 211
211void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) { 212void Module::Interface::GetStandardLocalSystemClock(HLERequestContext& ctx) {
212 LOG_DEBUG(Service_Time, "called"); 213 LOG_DEBUG(Service_Time, "called");
213 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 214 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
214 rb.Push(ResultSuccess); 215 rb.Push(ResultSuccess);
@@ -216,8 +217,7 @@ void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& c
216 system); 217 system);
217} 218}
218 219
219void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient( 220void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx) {
220 Kernel::HLERequestContext& ctx) {
221 LOG_DEBUG(Service_Time, "called"); 221 LOG_DEBUG(Service_Time, "called");
222 auto& clock_core{system.GetTimeManager().GetStandardNetworkSystemClockCore()}; 222 auto& clock_core{system.GetTimeManager().GetStandardNetworkSystemClockCore()};
223 IPC::ResponseBuilder rb{ctx, 3}; 223 IPC::ResponseBuilder rb{ctx, 3};
@@ -225,7 +225,7 @@ void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient(
225 rb.Push<u32>(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system)); 225 rb.Push<u32>(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system));
226} 226}
227 227
228void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx) { 228void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx) {
229 LOG_DEBUG(Service_Time, "called"); 229 LOG_DEBUG(Service_Time, "called");
230 230
231 auto& steady_clock_core{system.GetTimeManager().GetStandardSteadyClockCore()}; 231 auto& steady_clock_core{system.GetTimeManager().GetStandardSteadyClockCore()};
@@ -254,7 +254,7 @@ void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERe
254 rb.Push(ERROR_TIME_MISMATCH); 254 rb.Push(ERROR_TIME_MISMATCH);
255} 255}
256 256
257void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { 257void Module::Interface::GetClockSnapshot(HLERequestContext& ctx) {
258 IPC::RequestParser rp{ctx}; 258 IPC::RequestParser rp{ctx};
259 const auto type{rp.PopEnum<Clock::TimeType>()}; 259 const auto type{rp.PopEnum<Clock::TimeType>()};
260 260
@@ -295,7 +295,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
295 rb.Push(ResultSuccess); 295 rb.Push(ResultSuccess);
296} 296}
297 297
298void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx) { 298void Module::Interface::GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx) {
299 IPC::RequestParser rp{ctx}; 299 IPC::RequestParser rp{ctx};
300 const auto type{rp.PopEnum<Clock::TimeType>()}; 300 const auto type{rp.PopEnum<Clock::TimeType>()};
301 301
@@ -321,8 +321,7 @@ void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLEReques
321 rb.Push(ResultSuccess); 321 rb.Push(ResultSuccess);
322} 322}
323 323
324void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser( 324void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser(HLERequestContext& ctx) {
325 Kernel::HLERequestContext& ctx) {
326 LOG_DEBUG(Service_Time, "called"); 325 LOG_DEBUG(Service_Time, "called");
327 326
328 Clock::ClockSnapshot snapshot_a; 327 Clock::ClockSnapshot snapshot_a;
@@ -349,7 +348,7 @@ void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser(
349 rb.PushRaw(time_span_type.nanoseconds); 348 rb.PushRaw(time_span_type.nanoseconds);
350} 349}
351 350
352void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) { 351void Module::Interface::CalculateSpanBetween(HLERequestContext& ctx) {
353 LOG_DEBUG(Service_Time, "called"); 352 LOG_DEBUG(Service_Time, "called");
354 353
355 Clock::ClockSnapshot snapshot_a; 354 Clock::ClockSnapshot snapshot_a;
@@ -384,7 +383,7 @@ void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) {
384 rb.PushRaw(time_span_type.nanoseconds); 383 rb.PushRaw(time_span_type.nanoseconds);
385} 384}
386 385
387void Module::Interface::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { 386void Module::Interface::GetSharedMemoryNativeHandle(HLERequestContext& ctx) {
388 LOG_DEBUG(Service_Time, "called"); 387 LOG_DEBUG(Service_Time, "called");
389 IPC::ResponseBuilder rb{ctx, 2, 1}; 388 IPC::ResponseBuilder rb{ctx, 2, 1};
390 rb.Push(ResultSuccess); 389 rb.Push(ResultSuccess);
@@ -397,11 +396,17 @@ Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& syst
397 396
398Module::Interface::~Interface() = default; 397Module::Interface::~Interface() = default;
399 398
400void InstallInterfaces(Core::System& system) { 399void LoopProcess(Core::System& system) {
400 auto server_manager = std::make_unique<ServerManager>(system);
401 auto module{std::make_shared<Module>()}; 401 auto module{std::make_shared<Module>()};
402 std::make_shared<Time>(module, system, "time:a")->InstallAsService(system.ServiceManager()); 402
403 std::make_shared<Time>(module, system, "time:s")->InstallAsService(system.ServiceManager()); 403 server_manager->RegisterNamedService("time:a",
404 std::make_shared<Time>(module, system, "time:u")->InstallAsService(system.ServiceManager()); 404 std::make_shared<Time>(module, system, "time:a"));
405 server_manager->RegisterNamedService("time:s",
406 std::make_shared<Time>(module, system, "time:s"));
407 server_manager->RegisterNamedService("time:u",
408 std::make_shared<Time>(module, system, "time:u"));
409 ServerManager::RunServer(std::move(server_manager));
405} 410}
406 411
407} // namespace Service::Time 412} // namespace Service::Time
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index 76a46cfc7..b2d754ef3 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -22,18 +22,18 @@ public:
22 const char* name); 22 const char* name);
23 ~Interface() override; 23 ~Interface() override;
24 24
25 void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx); 25 void GetStandardUserSystemClock(HLERequestContext& ctx);
26 void GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx); 26 void GetStandardNetworkSystemClock(HLERequestContext& ctx);
27 void GetStandardSteadyClock(Kernel::HLERequestContext& ctx); 27 void GetStandardSteadyClock(HLERequestContext& ctx);
28 void GetTimeZoneService(Kernel::HLERequestContext& ctx); 28 void GetTimeZoneService(HLERequestContext& ctx);
29 void GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx); 29 void GetStandardLocalSystemClock(HLERequestContext& ctx);
30 void IsStandardNetworkSystemClockAccuracySufficient(Kernel::HLERequestContext& ctx); 30 void IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx);
31 void CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx); 31 void CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx);
32 void GetClockSnapshot(Kernel::HLERequestContext& ctx); 32 void GetClockSnapshot(HLERequestContext& ctx);
33 void GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx); 33 void GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx);
34 void CalculateStandardUserSystemClockDifferenceByUser(Kernel::HLERequestContext& ctx); 34 void CalculateStandardUserSystemClockDifferenceByUser(HLERequestContext& ctx);
35 void CalculateSpanBetween(Kernel::HLERequestContext& ctx); 35 void CalculateSpanBetween(HLERequestContext& ctx);
36 void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx); 36 void GetSharedMemoryNativeHandle(HLERequestContext& ctx);
37 37
38 private: 38 private:
39 Result GetClockSnapshotFromSystemClockContextInternal( 39 Result GetClockSnapshotFromSystemClockContextInternal(
@@ -46,7 +46,6 @@ public:
46 }; 46 };
47}; 47};
48 48
49/// Registers all Time services with the specified service manager. 49void LoopProcess(Core::System& system);
50void InstallInterfaces(Core::System& system);
51 50
52} // namespace Service::Time 51} // namespace Service::Time
diff --git a/src/core/hle/service/time/time_zone_service.cpp b/src/core/hle/service/time/time_zone_service.cpp
index 961040bfc..cda8d8343 100644
--- a/src/core/hle/service/time/time_zone_service.cpp
+++ b/src/core/hle/service/time/time_zone_service.cpp
@@ -2,7 +2,7 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h" 5#include "core/hle/service/ipc_helpers.h"
6#include "core/hle/service/time/time_zone_content_manager.h" 6#include "core/hle/service/time/time_zone_content_manager.h"
7#include "core/hle/service/time/time_zone_service.h" 7#include "core/hle/service/time/time_zone_service.h"
8#include "core/hle/service/time/time_zone_types.h" 8#include "core/hle/service/time/time_zone_types.h"
@@ -28,7 +28,7 @@ ITimeZoneService::ITimeZoneService(Core::System& system_,
28 RegisterHandlers(functions); 28 RegisterHandlers(functions);
29} 29}
30 30
31void ITimeZoneService::GetDeviceLocationName(Kernel::HLERequestContext& ctx) { 31void ITimeZoneService::GetDeviceLocationName(HLERequestContext& ctx) {
32 LOG_DEBUG(Service_Time, "called"); 32 LOG_DEBUG(Service_Time, "called");
33 33
34 TimeZone::LocationName location_name{}; 34 TimeZone::LocationName location_name{};
@@ -45,7 +45,7 @@ void ITimeZoneService::GetDeviceLocationName(Kernel::HLERequestContext& ctx) {
45 rb.PushRaw(location_name); 45 rb.PushRaw(location_name);
46} 46}
47 47
48void ITimeZoneService::LoadTimeZoneRule(Kernel::HLERequestContext& ctx) { 48void ITimeZoneService::LoadTimeZoneRule(HLERequestContext& ctx) {
49 IPC::RequestParser rp{ctx}; 49 IPC::RequestParser rp{ctx};
50 const auto raw_location_name{rp.PopRaw<std::array<u8, 0x24>>()}; 50 const auto raw_location_name{rp.PopRaw<std::array<u8, 0x24>>()};
51 51
@@ -77,7 +77,7 @@ void ITimeZoneService::LoadTimeZoneRule(Kernel::HLERequestContext& ctx) {
77 rb.Push(ResultSuccess); 77 rb.Push(ResultSuccess);
78} 78}
79 79
80void ITimeZoneService::ToCalendarTime(Kernel::HLERequestContext& ctx) { 80void ITimeZoneService::ToCalendarTime(HLERequestContext& ctx) {
81 IPC::RequestParser rp{ctx}; 81 IPC::RequestParser rp{ctx};
82 const auto posix_time{rp.Pop<s64>()}; 82 const auto posix_time{rp.Pop<s64>()};
83 83
@@ -101,7 +101,7 @@ void ITimeZoneService::ToCalendarTime(Kernel::HLERequestContext& ctx) {
101 rb.PushRaw(calendar_info); 101 rb.PushRaw(calendar_info);
102} 102}
103 103
104void ITimeZoneService::ToCalendarTimeWithMyRule(Kernel::HLERequestContext& ctx) { 104void ITimeZoneService::ToCalendarTimeWithMyRule(HLERequestContext& ctx) {
105 IPC::RequestParser rp{ctx}; 105 IPC::RequestParser rp{ctx};
106 const auto posix_time{rp.Pop<s64>()}; 106 const auto posix_time{rp.Pop<s64>()};
107 107
@@ -122,7 +122,7 @@ void ITimeZoneService::ToCalendarTimeWithMyRule(Kernel::HLERequestContext& ctx)
122 rb.PushRaw(calendar_info); 122 rb.PushRaw(calendar_info);
123} 123}
124 124
125void ITimeZoneService::ToPosixTime(Kernel::HLERequestContext& ctx) { 125void ITimeZoneService::ToPosixTime(HLERequestContext& ctx) {
126 LOG_DEBUG(Service_Time, "called"); 126 LOG_DEBUG(Service_Time, "called");
127 127
128 IPC::RequestParser rp{ctx}; 128 IPC::RequestParser rp{ctx};
@@ -147,7 +147,7 @@ void ITimeZoneService::ToPosixTime(Kernel::HLERequestContext& ctx) {
147 rb.PushRaw<u32>(1); // Number of times we're returning 147 rb.PushRaw<u32>(1); // Number of times we're returning
148} 148}
149 149
150void ITimeZoneService::ToPosixTimeWithMyRule(Kernel::HLERequestContext& ctx) { 150void ITimeZoneService::ToPosixTimeWithMyRule(HLERequestContext& ctx) {
151 LOG_DEBUG(Service_Time, "called"); 151 LOG_DEBUG(Service_Time, "called");
152 152
153 IPC::RequestParser rp{ctx}; 153 IPC::RequestParser rp{ctx};
diff --git a/src/core/hle/service/time/time_zone_service.h b/src/core/hle/service/time/time_zone_service.h
index f151f4b56..ea83b5714 100644
--- a/src/core/hle/service/time/time_zone_service.h
+++ b/src/core/hle/service/time/time_zone_service.h
@@ -21,12 +21,12 @@ public:
21 TimeZone::TimeZoneContentManager& time_zone_manager_); 21 TimeZone::TimeZoneContentManager& time_zone_manager_);
22 22
23private: 23private:
24 void GetDeviceLocationName(Kernel::HLERequestContext& ctx); 24 void GetDeviceLocationName(HLERequestContext& ctx);
25 void LoadTimeZoneRule(Kernel::HLERequestContext& ctx); 25 void LoadTimeZoneRule(HLERequestContext& ctx);
26 void ToCalendarTime(Kernel::HLERequestContext& ctx); 26 void ToCalendarTime(HLERequestContext& ctx);
27 void ToCalendarTimeWithMyRule(Kernel::HLERequestContext& ctx); 27 void ToCalendarTimeWithMyRule(HLERequestContext& ctx);
28 void ToPosixTime(Kernel::HLERequestContext& ctx); 28 void ToPosixTime(HLERequestContext& ctx);
29 void ToPosixTimeWithMyRule(Kernel::HLERequestContext& ctx); 29 void ToPosixTimeWithMyRule(HLERequestContext& ctx);
30 30
31private: 31private:
32 TimeZone::TimeZoneContentManager& time_zone_content_manager; 32 TimeZone::TimeZoneContentManager& time_zone_content_manager;
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp
index ac46a406c..f29fff1dd 100644
--- a/src/core/hle/service/usb/usb.cpp
+++ b/src/core/hle/service/usb/usb.cpp
@@ -4,9 +4,9 @@
4#include <memory> 4#include <memory>
5 5
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/hle/ipc_helpers.h" 7#include "core/hle/service/ipc_helpers.h"
8#include "core/hle/service/server_manager.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10#include "core/hle/service/usb/usb.h" 10#include "core/hle/service/usb/usb.h"
11 11
12namespace Service::USB { 12namespace Service::USB {
@@ -16,19 +16,19 @@ public:
16 explicit IDsInterface(Core::System& system_) : ServiceFramework{system_, "IDsInterface"} { 16 explicit IDsInterface(Core::System& system_) : ServiceFramework{system_, "IDsInterface"} {
17 // clang-format off 17 // clang-format off
18 static const FunctionInfo functions[] = { 18 static const FunctionInfo functions[] = {
19 {0, nullptr, "BindDevice"}, 19 {0, nullptr, "AddEndpoint"},
20 {1, nullptr, "BindClientProcess"}, 20 {1, nullptr, "GetSetupEvent"},
21 {2, nullptr, "AddInterface"}, 21 {2, nullptr, "GetSetupPacket"},
22 {3, nullptr, "GetStateChangeEvent"}, 22 {3, nullptr, "Enable"},
23 {4, nullptr, "GetState"}, 23 {4, nullptr, "Disable"},
24 {5, nullptr, "ClearDeviceData"}, 24 {5, nullptr, "CtrlIn"},
25 {6, nullptr, "AddUsbStringDescriptor"}, 25 {6, nullptr, "CtrlOut"},
26 {7, nullptr, "DeleteUsbStringDescriptor"}, 26 {7, nullptr, "GetCtrlInCompletionEvent"},
27 {8, nullptr, "SetUsbDeviceDescriptor"}, 27 {8, nullptr, "GetCtrlInUrbReport"},
28 {9, nullptr, "SetBinaryObjectStore"}, 28 {9, nullptr, "GetCtrlOutCompletionEvent"},
29 {10, nullptr, "Enable"}, 29 {10, nullptr, "GetCtrlOutUrbReport"},
30 {11, nullptr, "Disable"}, 30 {11, nullptr, "CtrlStall"},
31 {12, nullptr, "Unknown12"}, 31 {12, nullptr, "AppendConfigurationData"},
32 }; 32 };
33 // clang-format on 33 // clang-format on
34 34
@@ -36,9 +36,9 @@ public:
36 } 36 }
37}; 37};
38 38
39class USB_DS final : public ServiceFramework<USB_DS> { 39class IDsRootSession final : public ServiceFramework<IDsRootSession> {
40public: 40public:
41 explicit USB_DS(Core::System& system_) : ServiceFramework{system_, "usb:ds"} { 41 explicit IDsRootSession(Core::System& system_) : ServiceFramework{system_, "usb:ds"} {
42 // clang-format off 42 // clang-format off
43 static const FunctionInfo functions[] = { 43 static const FunctionInfo functions[] = {
44 {0, nullptr, "OpenDsService"}, 44 {0, nullptr, "OpenDsService"},
@@ -94,9 +94,9 @@ public:
94 } 94 }
95}; 95};
96 96
97class USB_HS final : public ServiceFramework<USB_HS> { 97class IClientRootSession final : public ServiceFramework<IClientRootSession> {
98public: 98public:
99 explicit USB_HS(Core::System& system_) : ServiceFramework{system_, "usb:hs"} { 99 explicit IClientRootSession(Core::System& system_) : ServiceFramework{system_, "usb:hs"} {
100 // clang-format off 100 // clang-format off
101 static const FunctionInfo functions[] = { 101 static const FunctionInfo functions[] = {
102 {0, nullptr, "BindClientProcess"}, 102 {0, nullptr, "BindClientProcess"},
@@ -107,7 +107,7 @@ public:
107 {5, nullptr, "DestroyInterfaceAvailableEvent"}, 107 {5, nullptr, "DestroyInterfaceAvailableEvent"},
108 {6, nullptr, "GetInterfaceStateChangeEvent"}, 108 {6, nullptr, "GetInterfaceStateChangeEvent"},
109 {7, nullptr, "AcquireUsbIf"}, 109 {7, nullptr, "AcquireUsbIf"},
110 {8, nullptr, "ResetDevice"}, 110 {8, nullptr, "SetTestMode"},
111 }; 111 };
112 // clang-format on 112 // clang-format on
113 113
@@ -134,12 +134,12 @@ public:
134 } 134 }
135}; 135};
136 136
137class USB_PD final : public ServiceFramework<USB_PD> { 137class IPdManager final : public ServiceFramework<IPdManager> {
138public: 138public:
139 explicit USB_PD(Core::System& system_) : ServiceFramework{system_, "usb:pd"} { 139 explicit IPdManager(Core::System& system_) : ServiceFramework{system_, "usb:pd"} {
140 // clang-format off 140 // clang-format off
141 static const FunctionInfo functions[] = { 141 static const FunctionInfo functions[] = {
142 {0, &USB_PD::GetPdSession, "GetPdSession"}, 142 {0, &IPdManager::OpenSession, "OpenSession"},
143 }; 143 };
144 // clang-format on 144 // clang-format on
145 145
@@ -147,7 +147,7 @@ public:
147 } 147 }
148 148
149private: 149private:
150 void GetPdSession(Kernel::HLERequestContext& ctx) { 150 void OpenSession(HLERequestContext& ctx) {
151 LOG_DEBUG(Service_USB, "called"); 151 LOG_DEBUG(Service_USB, "called");
152 152
153 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 153 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -178,12 +178,12 @@ public:
178 } 178 }
179}; 179};
180 180
181class USB_PD_C final : public ServiceFramework<USB_PD_C> { 181class IPdCradleManager final : public ServiceFramework<IPdCradleManager> {
182public: 182public:
183 explicit USB_PD_C(Core::System& system_) : ServiceFramework{system_, "usb:pd:c"} { 183 explicit IPdCradleManager(Core::System& system_) : ServiceFramework{system_, "usb:pd:c"} {
184 // clang-format off 184 // clang-format off
185 static const FunctionInfo functions[] = { 185 static const FunctionInfo functions[] = {
186 {0, &USB_PD_C::GetPdCradleSession, "GetPdCradleSession"}, 186 {0, &IPdCradleManager::OpenCradleSession, "OpenCradleSession"},
187 }; 187 };
188 // clang-format on 188 // clang-format on
189 189
@@ -191,18 +191,18 @@ public:
191 } 191 }
192 192
193private: 193private:
194 void GetPdCradleSession(Kernel::HLERequestContext& ctx) { 194 void OpenCradleSession(HLERequestContext& ctx) {
195 LOG_DEBUG(Service_USB, "called");
196
195 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 197 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
196 rb.Push(ResultSuccess); 198 rb.Push(ResultSuccess);
197 rb.PushIpcInterface<IPdCradleSession>(system); 199 rb.PushIpcInterface<IPdCradleSession>(system);
198
199 LOG_DEBUG(Service_USB, "called");
200 } 200 }
201}; 201};
202 202
203class USB_PM final : public ServiceFramework<USB_PM> { 203class IPmMainService final : public ServiceFramework<IPmMainService> {
204public: 204public:
205 explicit USB_PM(Core::System& system_) : ServiceFramework{system_, "usb:pm"} { 205 explicit IPmMainService(Core::System& system_) : ServiceFramework{system_, "usb:pm"} {
206 // clang-format off 206 // clang-format off
207 static const FunctionInfo functions[] = { 207 static const FunctionInfo functions[] = {
208 {0, nullptr, "GetPowerEvent"}, 208 {0, nullptr, "GetPowerEvent"},
@@ -218,12 +218,15 @@ public:
218 } 218 }
219}; 219};
220 220
221void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 221void LoopProcess(Core::System& system) {
222 std::make_shared<USB_DS>(system)->InstallAsService(sm); 222 auto server_manager = std::make_unique<ServerManager>(system);
223 std::make_shared<USB_HS>(system)->InstallAsService(sm); 223
224 std::make_shared<USB_PD>(system)->InstallAsService(sm); 224 server_manager->RegisterNamedService("usb:ds", std::make_shared<IDsRootSession>(system));
225 std::make_shared<USB_PD_C>(system)->InstallAsService(sm); 225 server_manager->RegisterNamedService("usb:hs", std::make_shared<IClientRootSession>(system));
226 std::make_shared<USB_PM>(system)->InstallAsService(sm); 226 server_manager->RegisterNamedService("usb:pd", std::make_shared<IPdManager>(system));
227 server_manager->RegisterNamedService("usb:pd:c", std::make_shared<IPdCradleManager>(system));
228 server_manager->RegisterNamedService("usb:pm", std::make_shared<IPmMainService>(system));
229 ServerManager::RunServer(std::move(server_manager));
227} 230}
228 231
229} // namespace Service::USB 232} // namespace Service::USB
diff --git a/src/core/hle/service/usb/usb.h b/src/core/hle/service/usb/usb.h
index b41b9684c..98376ebc0 100644
--- a/src/core/hle/service/usb/usb.h
+++ b/src/core/hle/service/usb/usb.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::USB { 10namespace Service::USB {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::USB 14} // namespace Service::USB
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp
index 8ef74f1f0..69af2868a 100644
--- a/src/core/hle/service/vi/display/vi_display.cpp
+++ b/src/core/hle/service/vi/display/vi_display.cpp
@@ -12,11 +12,11 @@
12#include "core/hle/kernel/k_readable_event.h" 12#include "core/hle/kernel/k_readable_event.h"
13#include "core/hle/service/kernel_helpers.h" 13#include "core/hle/service/kernel_helpers.h"
14#include "core/hle/service/nvdrv/core/container.h" 14#include "core/hle/service/nvdrv/core/container.h"
15#include "core/hle/service/nvflinger/buffer_item_consumer.h" 15#include "core/hle/service/nvnflinger/buffer_item_consumer.h"
16#include "core/hle/service/nvflinger/buffer_queue_consumer.h" 16#include "core/hle/service/nvnflinger/buffer_queue_consumer.h"
17#include "core/hle/service/nvflinger/buffer_queue_core.h" 17#include "core/hle/service/nvnflinger/buffer_queue_core.h"
18#include "core/hle/service/nvflinger/buffer_queue_producer.h" 18#include "core/hle/service/nvnflinger/buffer_queue_producer.h"
19#include "core/hle/service/nvflinger/hos_binder_driver_server.h" 19#include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
20#include "core/hle/service/vi/display/vi_display.h" 20#include "core/hle/service/vi/display/vi_display.h"
21#include "core/hle/service/vi/layer/vi_layer.h" 21#include "core/hle/service/vi/layer/vi_layer.h"
22#include "core/hle/service/vi/vi_results.h" 22#include "core/hle/service/vi/vi_results.h"
@@ -39,7 +39,7 @@ static BufferQueue CreateBufferQueue(KernelHelpers::ServiceContext& service_cont
39} 39}
40 40
41Display::Display(u64 id, std::string name_, 41Display::Display(u64 id, std::string name_,
42 NVFlinger::HosBinderDriverServer& hos_binder_driver_server_, 42 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_,
43 KernelHelpers::ServiceContext& service_context_, Core::System& system_) 43 KernelHelpers::ServiceContext& service_context_, Core::System& system_)
44 : display_id{id}, name{std::move(name_)}, hos_binder_driver_server{hos_binder_driver_server_}, 44 : display_id{id}, name{std::move(name_)}, hos_binder_driver_server{hos_binder_driver_server_},
45 service_context{service_context_} { 45 service_context{service_context_} {
diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h
index 0b65a65da..3f31d1f32 100644
--- a/src/core/hle/service/vi/display/vi_display.h
+++ b/src/core/hle/service/vi/display/vi_display.h
@@ -23,7 +23,7 @@ namespace Service::KernelHelpers {
23class ServiceContext; 23class ServiceContext;
24} 24}
25 25
26namespace Service::NVFlinger { 26namespace Service::Nvnflinger {
27class HosBinderDriverServer; 27class HosBinderDriverServer;
28} 28}
29 29
@@ -45,12 +45,12 @@ public:
45 /// Constructs a display with a given unique ID and name. 45 /// Constructs a display with a given unique ID and name.
46 /// 46 ///
47 /// @param id The unique ID for this display. 47 /// @param id The unique ID for this display.
48 /// @param hos_binder_driver_server_ NVFlinger HOSBinderDriver server instance. 48 /// @param hos_binder_driver_server_ Nvnflinger HOSBinderDriver server instance.
49 /// @param service_context_ The ServiceContext for the owning service. 49 /// @param service_context_ The ServiceContext for the owning service.
50 /// @param name_ The name for this display. 50 /// @param name_ The name for this display.
51 /// @param system_ The global system instance. 51 /// @param system_ The global system instance.
52 /// 52 ///
53 Display(u64 id, std::string name_, NVFlinger::HosBinderDriverServer& hos_binder_driver_server_, 53 Display(u64 id, std::string name_, Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_,
54 KernelHelpers::ServiceContext& service_context_, Core::System& system_); 54 KernelHelpers::ServiceContext& service_context_, Core::System& system_);
55 ~Display(); 55 ~Display();
56 56
@@ -133,7 +133,7 @@ public:
133private: 133private:
134 u64 display_id; 134 u64 display_id;
135 std::string name; 135 std::string name;
136 NVFlinger::HosBinderDriverServer& hos_binder_driver_server; 136 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server;
137 KernelHelpers::ServiceContext& service_context; 137 KernelHelpers::ServiceContext& service_context;
138 138
139 std::vector<std::unique_ptr<Layer>> layers; 139 std::vector<std::unique_ptr<Layer>> layers;
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 0915785d2..68eab5133 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -17,15 +17,16 @@
17#include "common/settings.h" 17#include "common/settings.h"
18#include "common/swap.h" 18#include "common/swap.h"
19#include "core/core_timing.h" 19#include "core/core_timing.h"
20#include "core/hle/ipc_helpers.h"
21#include "core/hle/kernel/k_readable_event.h" 20#include "core/hle/kernel/k_readable_event.h"
22#include "core/hle/kernel/k_thread.h" 21#include "core/hle/kernel/k_thread.h"
22#include "core/hle/service/ipc_helpers.h"
23#include "core/hle/service/nvdrv/nvdata.h" 23#include "core/hle/service/nvdrv/nvdata.h"
24#include "core/hle/service/nvflinger/binder.h" 24#include "core/hle/service/nvnflinger/binder.h"
25#include "core/hle/service/nvflinger/buffer_queue_producer.h" 25#include "core/hle/service/nvnflinger/buffer_queue_producer.h"
26#include "core/hle/service/nvflinger/hos_binder_driver_server.h" 26#include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
27#include "core/hle/service/nvflinger/nvflinger.h" 27#include "core/hle/service/nvnflinger/nvnflinger.h"
28#include "core/hle/service/nvflinger/parcel.h" 28#include "core/hle/service/nvnflinger/parcel.h"
29#include "core/hle/service/server_manager.h"
29#include "core/hle/service/service.h" 30#include "core/hle/service/service.h"
30#include "core/hle/service/vi/vi.h" 31#include "core/hle/service/vi/vi.h"
31#include "core/hle/service/vi/vi_m.h" 32#include "core/hle/service/vi/vi_m.h"
@@ -72,9 +73,8 @@ static_assert(sizeof(NativeWindow) == 0x28, "NativeWindow has wrong size");
72 73
73class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> { 74class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> {
74public: 75public:
75 explicit IHOSBinderDriver(Core::System& system_, NVFlinger::HosBinderDriverServer& server_) 76 explicit IHOSBinderDriver(Core::System& system_, Nvnflinger::HosBinderDriverServer& server_)
76 : ServiceFramework{system_, "IHOSBinderDriver", ServiceThreadType::CreateNew}, 77 : ServiceFramework{system_, "IHOSBinderDriver"}, server(server_) {
77 server(server_) {
78 static const FunctionInfo functions[] = { 78 static const FunctionInfo functions[] = {
79 {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, 79 {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"},
80 {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, 80 {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"},
@@ -85,7 +85,7 @@ public:
85 } 85 }
86 86
87private: 87private:
88 void TransactParcel(Kernel::HLERequestContext& ctx) { 88 void TransactParcel(HLERequestContext& ctx) {
89 IPC::RequestParser rp{ctx}; 89 IPC::RequestParser rp{ctx};
90 const u32 id = rp.Pop<u32>(); 90 const u32 id = rp.Pop<u32>();
91 const auto transaction = static_cast<android::TransactionId>(rp.Pop<u32>()); 91 const auto transaction = static_cast<android::TransactionId>(rp.Pop<u32>());
@@ -100,7 +100,7 @@ private:
100 rb.Push(ResultSuccess); 100 rb.Push(ResultSuccess);
101 } 101 }
102 102
103 void AdjustRefcount(Kernel::HLERequestContext& ctx) { 103 void AdjustRefcount(HLERequestContext& ctx) {
104 IPC::RequestParser rp{ctx}; 104 IPC::RequestParser rp{ctx};
105 const u32 id = rp.Pop<u32>(); 105 const u32 id = rp.Pop<u32>();
106 const s32 addval = rp.PopRaw<s32>(); 106 const s32 addval = rp.PopRaw<s32>();
@@ -113,7 +113,7 @@ private:
113 rb.Push(ResultSuccess); 113 rb.Push(ResultSuccess);
114 } 114 }
115 115
116 void GetNativeHandle(Kernel::HLERequestContext& ctx) { 116 void GetNativeHandle(HLERequestContext& ctx) {
117 IPC::RequestParser rp{ctx}; 117 IPC::RequestParser rp{ctx};
118 const u32 id = rp.Pop<u32>(); 118 const u32 id = rp.Pop<u32>();
119 const u32 unknown = rp.Pop<u32>(); 119 const u32 unknown = rp.Pop<u32>();
@@ -126,7 +126,7 @@ private:
126 } 126 }
127 127
128private: 128private:
129 NVFlinger::HosBinderDriverServer& server; 129 Nvnflinger::HosBinderDriverServer& server;
130}; 130};
131 131
132class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> { 132class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> {
@@ -186,7 +186,7 @@ public:
186 } 186 }
187 187
188private: 188private:
189 void SetLayerZ(Kernel::HLERequestContext& ctx) { 189 void SetLayerZ(HLERequestContext& ctx) {
190 IPC::RequestParser rp{ctx}; 190 IPC::RequestParser rp{ctx};
191 const u64 layer_id = rp.Pop<u64>(); 191 const u64 layer_id = rp.Pop<u64>();
192 const u64 z_value = rp.Pop<u64>(); 192 const u64 z_value = rp.Pop<u64>();
@@ -200,7 +200,7 @@ private:
200 200
201 // This function currently does nothing but return a success error code in 201 // This function currently does nothing but return a success error code in
202 // the vi library itself, so do the same thing, but log out the passed in values. 202 // the vi library itself, so do the same thing, but log out the passed in values.
203 void SetLayerVisibility(Kernel::HLERequestContext& ctx) { 203 void SetLayerVisibility(HLERequestContext& ctx) {
204 IPC::RequestParser rp{ctx}; 204 IPC::RequestParser rp{ctx};
205 const u64 layer_id = rp.Pop<u64>(); 205 const u64 layer_id = rp.Pop<u64>();
206 const bool visibility = rp.Pop<bool>(); 206 const bool visibility = rp.Pop<bool>();
@@ -211,7 +211,7 @@ private:
211 rb.Push(ResultSuccess); 211 rb.Push(ResultSuccess);
212 } 212 }
213 213
214 void GetDisplayMode(Kernel::HLERequestContext& ctx) { 214 void GetDisplayMode(HLERequestContext& ctx) {
215 LOG_WARNING(Service_VI, "(STUBBED) called"); 215 LOG_WARNING(Service_VI, "(STUBBED) called");
216 216
217 IPC::ResponseBuilder rb{ctx, 6}; 217 IPC::ResponseBuilder rb{ctx, 6};
@@ -232,7 +232,7 @@ private:
232 232
233class IManagerDisplayService final : public ServiceFramework<IManagerDisplayService> { 233class IManagerDisplayService final : public ServiceFramework<IManagerDisplayService> {
234public: 234public:
235 explicit IManagerDisplayService(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_) 235 explicit IManagerDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nv_flinger_)
236 : ServiceFramework{system_, "IManagerDisplayService"}, nv_flinger{nv_flinger_} { 236 : ServiceFramework{system_, "IManagerDisplayService"}, nv_flinger{nv_flinger_} {
237 // clang-format off 237 // clang-format off
238 static const FunctionInfo functions[] = { 238 static const FunctionInfo functions[] = {
@@ -325,7 +325,7 @@ public:
325 } 325 }
326 326
327private: 327private:
328 void CloseDisplay(Kernel::HLERequestContext& ctx) { 328 void CloseDisplay(HLERequestContext& ctx) {
329 IPC::RequestParser rp{ctx}; 329 IPC::RequestParser rp{ctx};
330 const u64 display = rp.Pop<u64>(); 330 const u64 display = rp.Pop<u64>();
331 331
@@ -335,7 +335,7 @@ private:
335 rb.Push(rc); 335 rb.Push(rc);
336 } 336 }
337 337
338 void CreateManagedLayer(Kernel::HLERequestContext& ctx) { 338 void CreateManagedLayer(HLERequestContext& ctx) {
339 IPC::RequestParser rp{ctx}; 339 IPC::RequestParser rp{ctx};
340 const u32 unknown = rp.Pop<u32>(); 340 const u32 unknown = rp.Pop<u32>();
341 rp.Skip(1, false); 341 rp.Skip(1, false);
@@ -359,7 +359,7 @@ private:
359 rb.Push(*layer_id); 359 rb.Push(*layer_id);
360 } 360 }
361 361
362 void AddToLayerStack(Kernel::HLERequestContext& ctx) { 362 void AddToLayerStack(HLERequestContext& ctx) {
363 IPC::RequestParser rp{ctx}; 363 IPC::RequestParser rp{ctx};
364 const u32 stack = rp.Pop<u32>(); 364 const u32 stack = rp.Pop<u32>();
365 const u64 layer_id = rp.Pop<u64>(); 365 const u64 layer_id = rp.Pop<u64>();
@@ -371,7 +371,7 @@ private:
371 rb.Push(ResultSuccess); 371 rb.Push(ResultSuccess);
372 } 372 }
373 373
374 void SetLayerVisibility(Kernel::HLERequestContext& ctx) { 374 void SetLayerVisibility(HLERequestContext& ctx) {
375 IPC::RequestParser rp{ctx}; 375 IPC::RequestParser rp{ctx};
376 const u64 layer_id = rp.Pop<u64>(); 376 const u64 layer_id = rp.Pop<u64>();
377 const bool visibility = rp.Pop<bool>(); 377 const bool visibility = rp.Pop<bool>();
@@ -383,13 +383,13 @@ private:
383 rb.Push(ResultSuccess); 383 rb.Push(ResultSuccess);
384 } 384 }
385 385
386 NVFlinger::NVFlinger& nv_flinger; 386 Nvnflinger::Nvnflinger& nv_flinger;
387}; 387};
388 388
389class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> { 389class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> {
390public: 390public:
391 IApplicationDisplayService(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_, 391 IApplicationDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nv_flinger_,
392 NVFlinger::HosBinderDriverServer& hos_binder_driver_server_) 392 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_)
393 : ServiceFramework{system_, "IApplicationDisplayService"}, nv_flinger{nv_flinger_}, 393 : ServiceFramework{system_, "IApplicationDisplayService"}, nv_flinger{nv_flinger_},
394 hos_binder_driver_server{hos_binder_driver_server_} { 394 hos_binder_driver_server{hos_binder_driver_server_} {
395 395
@@ -440,7 +440,7 @@ private:
440 PreserveAspectRatio = 4, 440 PreserveAspectRatio = 4,
441 }; 441 };
442 442
443 void GetRelayService(Kernel::HLERequestContext& ctx) { 443 void GetRelayService(HLERequestContext& ctx) {
444 LOG_WARNING(Service_VI, "(STUBBED) called"); 444 LOG_WARNING(Service_VI, "(STUBBED) called");
445 445
446 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 446 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -448,7 +448,7 @@ private:
448 rb.PushIpcInterface<IHOSBinderDriver>(system, hos_binder_driver_server); 448 rb.PushIpcInterface<IHOSBinderDriver>(system, hos_binder_driver_server);
449 } 449 }
450 450
451 void GetSystemDisplayService(Kernel::HLERequestContext& ctx) { 451 void GetSystemDisplayService(HLERequestContext& ctx) {
452 LOG_WARNING(Service_VI, "(STUBBED) called"); 452 LOG_WARNING(Service_VI, "(STUBBED) called");
453 453
454 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 454 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -456,7 +456,7 @@ private:
456 rb.PushIpcInterface<ISystemDisplayService>(system); 456 rb.PushIpcInterface<ISystemDisplayService>(system);
457 } 457 }
458 458
459 void GetManagerDisplayService(Kernel::HLERequestContext& ctx) { 459 void GetManagerDisplayService(HLERequestContext& ctx) {
460 LOG_WARNING(Service_VI, "(STUBBED) called"); 460 LOG_WARNING(Service_VI, "(STUBBED) called");
461 461
462 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 462 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -464,7 +464,7 @@ private:
464 rb.PushIpcInterface<IManagerDisplayService>(system, nv_flinger); 464 rb.PushIpcInterface<IManagerDisplayService>(system, nv_flinger);
465 } 465 }
466 466
467 void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx) { 467 void GetIndirectDisplayTransactionService(HLERequestContext& ctx) {
468 LOG_WARNING(Service_VI, "(STUBBED) called"); 468 LOG_WARNING(Service_VI, "(STUBBED) called");
469 469
470 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 470 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -472,7 +472,7 @@ private:
472 rb.PushIpcInterface<IHOSBinderDriver>(system, hos_binder_driver_server); 472 rb.PushIpcInterface<IHOSBinderDriver>(system, hos_binder_driver_server);
473 } 473 }
474 474
475 void OpenDisplay(Kernel::HLERequestContext& ctx) { 475 void OpenDisplay(HLERequestContext& ctx) {
476 LOG_WARNING(Service_VI, "(STUBBED) called"); 476 LOG_WARNING(Service_VI, "(STUBBED) called");
477 477
478 IPC::RequestParser rp{ctx}; 478 IPC::RequestParser rp{ctx};
@@ -481,13 +481,13 @@ private:
481 OpenDisplayImpl(ctx, std::string_view{name_buf.data(), name_buf.size()}); 481 OpenDisplayImpl(ctx, std::string_view{name_buf.data(), name_buf.size()});
482 } 482 }
483 483
484 void OpenDefaultDisplay(Kernel::HLERequestContext& ctx) { 484 void OpenDefaultDisplay(HLERequestContext& ctx) {
485 LOG_DEBUG(Service_VI, "called"); 485 LOG_DEBUG(Service_VI, "called");
486 486
487 OpenDisplayImpl(ctx, "Default"); 487 OpenDisplayImpl(ctx, "Default");
488 } 488 }
489 489
490 void OpenDisplayImpl(Kernel::HLERequestContext& ctx, std::string_view name) { 490 void OpenDisplayImpl(HLERequestContext& ctx, std::string_view name) {
491 const auto trim_pos = name.find('\0'); 491 const auto trim_pos = name.find('\0');
492 492
493 if (trim_pos != std::string_view::npos) { 493 if (trim_pos != std::string_view::npos) {
@@ -509,7 +509,7 @@ private:
509 rb.Push<u64>(*display_id); 509 rb.Push<u64>(*display_id);
510 } 510 }
511 511
512 void CloseDisplay(Kernel::HLERequestContext& ctx) { 512 void CloseDisplay(HLERequestContext& ctx) {
513 IPC::RequestParser rp{ctx}; 513 IPC::RequestParser rp{ctx};
514 const u64 display_id = rp.Pop<u64>(); 514 const u64 display_id = rp.Pop<u64>();
515 515
@@ -521,14 +521,14 @@ private:
521 521
522 // This literally does nothing internally in the actual service itself, 522 // This literally does nothing internally in the actual service itself,
523 // and just returns a successful result code regardless of the input. 523 // and just returns a successful result code regardless of the input.
524 void SetDisplayEnabled(Kernel::HLERequestContext& ctx) { 524 void SetDisplayEnabled(HLERequestContext& ctx) {
525 LOG_DEBUG(Service_VI, "called."); 525 LOG_DEBUG(Service_VI, "called.");
526 526
527 IPC::ResponseBuilder rb{ctx, 2}; 527 IPC::ResponseBuilder rb{ctx, 2};
528 rb.Push(ResultSuccess); 528 rb.Push(ResultSuccess);
529 } 529 }
530 530
531 void GetDisplayResolution(Kernel::HLERequestContext& ctx) { 531 void GetDisplayResolution(HLERequestContext& ctx) {
532 IPC::RequestParser rp{ctx}; 532 IPC::RequestParser rp{ctx};
533 const u64 display_id = rp.Pop<u64>(); 533 const u64 display_id = rp.Pop<u64>();
534 534
@@ -544,7 +544,7 @@ private:
544 rb.Push(static_cast<u64>(DisplayResolution::UndockedHeight)); 544 rb.Push(static_cast<u64>(DisplayResolution::UndockedHeight));
545 } 545 }
546 546
547 void SetLayerScalingMode(Kernel::HLERequestContext& ctx) { 547 void SetLayerScalingMode(HLERequestContext& ctx) {
548 IPC::RequestParser rp{ctx}; 548 IPC::RequestParser rp{ctx};
549 const auto scaling_mode = rp.PopEnum<NintendoScaleMode>(); 549 const auto scaling_mode = rp.PopEnum<NintendoScaleMode>();
550 const u64 unknown = rp.Pop<u64>(); 550 const u64 unknown = rp.Pop<u64>();
@@ -570,7 +570,7 @@ private:
570 rb.Push(ResultSuccess); 570 rb.Push(ResultSuccess);
571 } 571 }
572 572
573 void ListDisplays(Kernel::HLERequestContext& ctx) { 573 void ListDisplays(HLERequestContext& ctx) {
574 LOG_WARNING(Service_VI, "(STUBBED) called"); 574 LOG_WARNING(Service_VI, "(STUBBED) called");
575 575
576 const DisplayInfo display_info; 576 const DisplayInfo display_info;
@@ -580,7 +580,7 @@ private:
580 rb.Push<u64>(1); 580 rb.Push<u64>(1);
581 } 581 }
582 582
583 void OpenLayer(Kernel::HLERequestContext& ctx) { 583 void OpenLayer(HLERequestContext& ctx) {
584 IPC::RequestParser rp{ctx}; 584 IPC::RequestParser rp{ctx};
585 const auto name_buf = rp.PopRaw<std::array<u8, 0x40>>(); 585 const auto name_buf = rp.PopRaw<std::array<u8, 0x40>>();
586 const auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); 586 const auto end = std::find(name_buf.begin(), name_buf.end(), '\0');
@@ -616,7 +616,7 @@ private:
616 rb.Push<u64>(buffer_size); 616 rb.Push<u64>(buffer_size);
617 } 617 }
618 618
619 void CloseLayer(Kernel::HLERequestContext& ctx) { 619 void CloseLayer(HLERequestContext& ctx) {
620 IPC::RequestParser rp{ctx}; 620 IPC::RequestParser rp{ctx};
621 const auto layer_id{rp.Pop<u64>()}; 621 const auto layer_id{rp.Pop<u64>()};
622 622
@@ -628,7 +628,7 @@ private:
628 rb.Push(ResultSuccess); 628 rb.Push(ResultSuccess);
629 } 629 }
630 630
631 void CreateStrayLayer(Kernel::HLERequestContext& ctx) { 631 void CreateStrayLayer(HLERequestContext& ctx) {
632 IPC::RequestParser rp{ctx}; 632 IPC::RequestParser rp{ctx};
633 const u32 flags = rp.Pop<u32>(); 633 const u32 flags = rp.Pop<u32>();
634 rp.Pop<u32>(); // padding 634 rp.Pop<u32>(); // padding
@@ -663,7 +663,7 @@ private:
663 rb.Push<u64>(buffer_size); 663 rb.Push<u64>(buffer_size);
664 } 664 }
665 665
666 void DestroyStrayLayer(Kernel::HLERequestContext& ctx) { 666 void DestroyStrayLayer(HLERequestContext& ctx) {
667 IPC::RequestParser rp{ctx}; 667 IPC::RequestParser rp{ctx};
668 const u64 layer_id = rp.Pop<u64>(); 668 const u64 layer_id = rp.Pop<u64>();
669 669
@@ -673,7 +673,7 @@ private:
673 rb.Push(ResultSuccess); 673 rb.Push(ResultSuccess);
674 } 674 }
675 675
676 void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx) { 676 void GetDisplayVsyncEvent(HLERequestContext& ctx) {
677 IPC::RequestParser rp{ctx}; 677 IPC::RequestParser rp{ctx};
678 const u64 display_id = rp.Pop<u64>(); 678 const u64 display_id = rp.Pop<u64>();
679 679
@@ -696,7 +696,7 @@ private:
696 rb.PushCopyObjects(*vsync_event); 696 rb.PushCopyObjects(*vsync_event);
697 } 697 }
698 698
699 void ConvertScalingMode(Kernel::HLERequestContext& ctx) { 699 void ConvertScalingMode(HLERequestContext& ctx) {
700 IPC::RequestParser rp{ctx}; 700 IPC::RequestParser rp{ctx};
701 const auto mode = rp.PopEnum<NintendoScaleMode>(); 701 const auto mode = rp.PopEnum<NintendoScaleMode>();
702 LOG_DEBUG(Service_VI, "called mode={}", mode); 702 LOG_DEBUG(Service_VI, "called mode={}", mode);
@@ -713,7 +713,7 @@ private:
713 } 713 }
714 } 714 }
715 715
716 void GetIndirectLayerImageMap(Kernel::HLERequestContext& ctx) { 716 void GetIndirectLayerImageMap(HLERequestContext& ctx) {
717 IPC::RequestParser rp{ctx}; 717 IPC::RequestParser rp{ctx};
718 const auto width = rp.Pop<s64>(); 718 const auto width = rp.Pop<s64>();
719 const auto height = rp.Pop<s64>(); 719 const auto height = rp.Pop<s64>();
@@ -739,7 +739,7 @@ private:
739 rb.Push(ResultSuccess); 739 rb.Push(ResultSuccess);
740 } 740 }
741 741
742 void GetIndirectLayerImageRequiredMemoryInfo(Kernel::HLERequestContext& ctx) { 742 void GetIndirectLayerImageRequiredMemoryInfo(HLERequestContext& ctx) {
743 IPC::RequestParser rp{ctx}; 743 IPC::RequestParser rp{ctx};
744 const auto width = rp.Pop<u64>(); 744 const auto width = rp.Pop<u64>();
745 const auto height = rp.Pop<u64>(); 745 const auto height = rp.Pop<u64>();
@@ -774,8 +774,8 @@ private:
774 } 774 }
775 } 775 }
776 776
777 NVFlinger::NVFlinger& nv_flinger; 777 Nvnflinger::Nvnflinger& nv_flinger;
778 NVFlinger::HosBinderDriverServer& hos_binder_driver_server; 778 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server;
779}; 779};
780 780
781static bool IsValidServiceAccess(Permission permission, Policy policy) { 781static bool IsValidServiceAccess(Permission permission, Policy policy) {
@@ -790,9 +790,9 @@ static bool IsValidServiceAccess(Permission permission, Policy policy) {
790 return false; 790 return false;
791} 791}
792 792
793void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System& system, 793void detail::GetDisplayServiceImpl(HLERequestContext& ctx, Core::System& system,
794 NVFlinger::NVFlinger& nv_flinger, 794 Nvnflinger::Nvnflinger& nv_flinger,
795 NVFlinger::HosBinderDriverServer& hos_binder_driver_server, 795 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server,
796 Permission permission) { 796 Permission permission) {
797 IPC::RequestParser rp{ctx}; 797 IPC::RequestParser rp{ctx};
798 const auto policy = rp.PopEnum<Policy>(); 798 const auto policy = rp.PopEnum<Policy>();
@@ -809,15 +809,17 @@ void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System&
809 rb.PushIpcInterface<IApplicationDisplayService>(system, nv_flinger, hos_binder_driver_server); 809 rb.PushIpcInterface<IApplicationDisplayService>(system, nv_flinger, hos_binder_driver_server);
810} 810}
811 811
812void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system, 812void LoopProcess(Core::System& system, Nvnflinger::Nvnflinger& nv_flinger,
813 NVFlinger::NVFlinger& nv_flinger, 813 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server) {
814 NVFlinger::HosBinderDriverServer& hos_binder_driver_server) { 814 auto server_manager = std::make_unique<ServerManager>(system);
815 std::make_shared<VI_M>(system, nv_flinger, hos_binder_driver_server) 815
816 ->InstallAsService(service_manager); 816 server_manager->RegisterNamedService(
817 std::make_shared<VI_S>(system, nv_flinger, hos_binder_driver_server) 817 "vi:m", std::make_shared<VI_M>(system, nv_flinger, hos_binder_driver_server));
818 ->InstallAsService(service_manager); 818 server_manager->RegisterNamedService(
819 std::make_shared<VI_U>(system, nv_flinger, hos_binder_driver_server) 819 "vi:s", std::make_shared<VI_S>(system, nv_flinger, hos_binder_driver_server));
820 ->InstallAsService(service_manager); 820 server_manager->RegisterNamedService(
821 "vi:u", std::make_shared<VI_U>(system, nv_flinger, hos_binder_driver_server));
822 ServerManager::RunServer(std::move(server_manager));
821} 823}
822 824
823} // namespace Service::VI 825} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h
index fc2d717e7..a35b62f97 100644
--- a/src/core/hle/service/vi/vi.h
+++ b/src/core/hle/service/vi/vi.h
@@ -9,18 +9,14 @@ namespace Core {
9class System; 9class System;
10} 10}
11 11
12namespace Kernel { 12namespace Service {
13class HLERequestContext; 13class HLERequestContext;
14} 14}
15 15
16namespace Service::NVFlinger { 16namespace Service::Nvnflinger {
17class HosBinderDriverServer; 17class HosBinderDriverServer;
18class NVFlinger; 18class Nvnflinger;
19} // namespace Service::NVFlinger 19} // namespace Service::Nvnflinger
20
21namespace Service::SM {
22class ServiceManager;
23}
24 20
25namespace Service::VI { 21namespace Service::VI {
26 22
@@ -46,15 +42,13 @@ enum class Policy {
46}; 42};
47 43
48namespace detail { 44namespace detail {
49void GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System& system, 45void GetDisplayServiceImpl(HLERequestContext& ctx, Core::System& system,
50 NVFlinger::NVFlinger& nv_flinger, 46 Nvnflinger::Nvnflinger& nv_flinger,
51 NVFlinger::HosBinderDriverServer& hos_binder_driver_server, 47 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server,
52 Permission permission); 48 Permission permission);
53} // namespace detail 49} // namespace detail
54 50
55/// Registers all VI services with the specified service manager. 51void LoopProcess(Core::System& system, Nvnflinger::Nvnflinger& nv_flinger,
56void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system, 52 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server);
57 NVFlinger::NVFlinger& nv_flinger,
58 NVFlinger::HosBinderDriverServer& hos_binder_driver_server);
59 53
60} // namespace Service::VI 54} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_m.cpp b/src/core/hle/service/vi/vi_m.cpp
index 7ca44354b..0f06dc2f3 100644
--- a/src/core/hle/service/vi/vi_m.cpp
+++ b/src/core/hle/service/vi/vi_m.cpp
@@ -7,8 +7,8 @@
7 7
8namespace Service::VI { 8namespace Service::VI {
9 9
10VI_M::VI_M(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_, 10VI_M::VI_M(Core::System& system_, Nvnflinger::Nvnflinger& nv_flinger_,
11 NVFlinger::HosBinderDriverServer& hos_binder_driver_server_) 11 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_)
12 : ServiceFramework{system_, "vi:m"}, nv_flinger{nv_flinger_}, hos_binder_driver_server{ 12 : ServiceFramework{system_, "vi:m"}, nv_flinger{nv_flinger_}, hos_binder_driver_server{
13 hos_binder_driver_server_} { 13 hos_binder_driver_server_} {
14 static const FunctionInfo functions[] = { 14 static const FunctionInfo functions[] = {
@@ -24,7 +24,7 @@ VI_M::VI_M(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_,
24 24
25VI_M::~VI_M() = default; 25VI_M::~VI_M() = default;
26 26
27void VI_M::GetDisplayService(Kernel::HLERequestContext& ctx) { 27void VI_M::GetDisplayService(HLERequestContext& ctx) {
28 LOG_DEBUG(Service_VI, "called"); 28 LOG_DEBUG(Service_VI, "called");
29 29
30 detail::GetDisplayServiceImpl(ctx, system, nv_flinger, hos_binder_driver_server, 30 detail::GetDisplayServiceImpl(ctx, system, nv_flinger, hos_binder_driver_server,
diff --git a/src/core/hle/service/vi/vi_m.h b/src/core/hle/service/vi/vi_m.h
index 3bf76d439..9ca6f3905 100644
--- a/src/core/hle/service/vi/vi_m.h
+++ b/src/core/hle/service/vi/vi_m.h
@@ -9,28 +9,24 @@ namespace Core {
9class System; 9class System;
10} 10}
11 11
12namespace Kernel { 12namespace Service::Nvnflinger {
13class HLERequestContext;
14}
15
16namespace Service::NVFlinger {
17class HosBinderDriverServer; 13class HosBinderDriverServer;
18class NVFlinger; 14class Nvnflinger;
19} // namespace Service::NVFlinger 15} // namespace Service::Nvnflinger
20 16
21namespace Service::VI { 17namespace Service::VI {
22 18
23class VI_M final : public ServiceFramework<VI_M> { 19class VI_M final : public ServiceFramework<VI_M> {
24public: 20public:
25 explicit VI_M(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_, 21 explicit VI_M(Core::System& system_, Nvnflinger::Nvnflinger& nv_flinger_,
26 NVFlinger::HosBinderDriverServer& hos_binder_driver_server_); 22 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_);
27 ~VI_M() override; 23 ~VI_M() override;
28 24
29private: 25private:
30 void GetDisplayService(Kernel::HLERequestContext& ctx); 26 void GetDisplayService(HLERequestContext& ctx);
31 27
32 NVFlinger::NVFlinger& nv_flinger; 28 Nvnflinger::Nvnflinger& nv_flinger;
33 NVFlinger::HosBinderDriverServer& hos_binder_driver_server; 29 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server;
34}; 30};
35 31
36} // namespace Service::VI 32} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_s.cpp b/src/core/hle/service/vi/vi_s.cpp
index fd799dac1..77f7a88ff 100644
--- a/src/core/hle/service/vi/vi_s.cpp
+++ b/src/core/hle/service/vi/vi_s.cpp
@@ -7,8 +7,8 @@
7 7
8namespace Service::VI { 8namespace Service::VI {
9 9
10VI_S::VI_S(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_, 10VI_S::VI_S(Core::System& system_, Nvnflinger::Nvnflinger& nv_flinger_,
11 NVFlinger::HosBinderDriverServer& hos_binder_driver_server_) 11 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_)
12 : ServiceFramework{system_, "vi:s"}, nv_flinger{nv_flinger_}, hos_binder_driver_server{ 12 : ServiceFramework{system_, "vi:s"}, nv_flinger{nv_flinger_}, hos_binder_driver_server{
13 hos_binder_driver_server_} { 13 hos_binder_driver_server_} {
14 static const FunctionInfo functions[] = { 14 static const FunctionInfo functions[] = {
@@ -20,7 +20,7 @@ VI_S::VI_S(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_,
20 20
21VI_S::~VI_S() = default; 21VI_S::~VI_S() = default;
22 22
23void VI_S::GetDisplayService(Kernel::HLERequestContext& ctx) { 23void VI_S::GetDisplayService(HLERequestContext& ctx) {
24 LOG_DEBUG(Service_VI, "called"); 24 LOG_DEBUG(Service_VI, "called");
25 25
26 detail::GetDisplayServiceImpl(ctx, system, nv_flinger, hos_binder_driver_server, 26 detail::GetDisplayServiceImpl(ctx, system, nv_flinger, hos_binder_driver_server,
diff --git a/src/core/hle/service/vi/vi_s.h b/src/core/hle/service/vi/vi_s.h
index 97503ac7f..157839c91 100644
--- a/src/core/hle/service/vi/vi_s.h
+++ b/src/core/hle/service/vi/vi_s.h
@@ -9,28 +9,24 @@ namespace Core {
9class System; 9class System;
10} 10}
11 11
12namespace Kernel { 12namespace Service::Nvnflinger {
13class HLERequestContext;
14}
15
16namespace Service::NVFlinger {
17class HosBinderDriverServer; 13class HosBinderDriverServer;
18class NVFlinger; 14class Nvnflinger;
19} // namespace Service::NVFlinger 15} // namespace Service::Nvnflinger
20 16
21namespace Service::VI { 17namespace Service::VI {
22 18
23class VI_S final : public ServiceFramework<VI_S> { 19class VI_S final : public ServiceFramework<VI_S> {
24public: 20public:
25 explicit VI_S(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_, 21 explicit VI_S(Core::System& system_, Nvnflinger::Nvnflinger& nv_flinger_,
26 NVFlinger::HosBinderDriverServer& hos_binder_driver_server_); 22 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_);
27 ~VI_S() override; 23 ~VI_S() override;
28 24
29private: 25private:
30 void GetDisplayService(Kernel::HLERequestContext& ctx); 26 void GetDisplayService(HLERequestContext& ctx);
31 27
32 NVFlinger::NVFlinger& nv_flinger; 28 Nvnflinger::Nvnflinger& nv_flinger;
33 NVFlinger::HosBinderDriverServer& hos_binder_driver_server; 29 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server;
34}; 30};
35 31
36} // namespace Service::VI 32} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi_u.cpp b/src/core/hle/service/vi/vi_u.cpp
index 6cc54bd13..59e13c86b 100644
--- a/src/core/hle/service/vi/vi_u.cpp
+++ b/src/core/hle/service/vi/vi_u.cpp
@@ -7,8 +7,8 @@
7 7
8namespace Service::VI { 8namespace Service::VI {
9 9
10VI_U::VI_U(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_, 10VI_U::VI_U(Core::System& system_, Nvnflinger::Nvnflinger& nv_flinger_,
11 NVFlinger::HosBinderDriverServer& hos_binder_driver_server_) 11 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_)
12 : ServiceFramework{system_, "vi:u"}, nv_flinger{nv_flinger_}, hos_binder_driver_server{ 12 : ServiceFramework{system_, "vi:u"}, nv_flinger{nv_flinger_}, hos_binder_driver_server{
13 hos_binder_driver_server_} { 13 hos_binder_driver_server_} {
14 static const FunctionInfo functions[] = { 14 static const FunctionInfo functions[] = {
@@ -20,7 +20,7 @@ VI_U::VI_U(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_,
20 20
21VI_U::~VI_U() = default; 21VI_U::~VI_U() = default;
22 22
23void VI_U::GetDisplayService(Kernel::HLERequestContext& ctx) { 23void VI_U::GetDisplayService(HLERequestContext& ctx) {
24 LOG_DEBUG(Service_VI, "called"); 24 LOG_DEBUG(Service_VI, "called");
25 25
26 detail::GetDisplayServiceImpl(ctx, system, nv_flinger, hos_binder_driver_server, 26 detail::GetDisplayServiceImpl(ctx, system, nv_flinger, hos_binder_driver_server,
diff --git a/src/core/hle/service/vi/vi_u.h b/src/core/hle/service/vi/vi_u.h
index 797941bd7..5d9ca54c6 100644
--- a/src/core/hle/service/vi/vi_u.h
+++ b/src/core/hle/service/vi/vi_u.h
@@ -9,28 +9,24 @@ namespace Core {
9class System; 9class System;
10} 10}
11 11
12namespace Kernel { 12namespace Service::Nvnflinger {
13class HLERequestContext;
14}
15
16namespace Service::NVFlinger {
17class HosBinderDriverServer; 13class HosBinderDriverServer;
18class NVFlinger; 14class Nvnflinger;
19} // namespace Service::NVFlinger 15} // namespace Service::Nvnflinger
20 16
21namespace Service::VI { 17namespace Service::VI {
22 18
23class VI_U final : public ServiceFramework<VI_U> { 19class VI_U final : public ServiceFramework<VI_U> {
24public: 20public:
25 explicit VI_U(Core::System& system_, NVFlinger::NVFlinger& nv_flinger_, 21 explicit VI_U(Core::System& system_, Nvnflinger::Nvnflinger& nv_flinger_,
26 NVFlinger::HosBinderDriverServer& hos_binder_driver_server_); 22 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_);
27 ~VI_U() override; 23 ~VI_U() override;
28 24
29private: 25private:
30 void GetDisplayService(Kernel::HLERequestContext& ctx); 26 void GetDisplayService(HLERequestContext& ctx);
31 27
32 NVFlinger::NVFlinger& nv_flinger; 28 Nvnflinger::Nvnflinger& nv_flinger;
33 NVFlinger::HosBinderDriverServer& hos_binder_driver_server; 29 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server;
34}; 30};
35 31
36} // namespace Service::VI 32} // namespace Service::VI
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index 44ee39648..c2d96bbec 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -47,8 +47,13 @@ void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size)
47} 47}
48 48
49u64 StandardVmCallbacks::HidKeysDown() { 49u64 StandardVmCallbacks::HidKeysDown() {
50 const auto applet_resource = 50 const auto hid = system.ServiceManager().GetService<Service::HID::Hid>("hid");
51 system.ServiceManager().GetService<Service::HID::Hid>("hid")->GetAppletResource(); 51 if (hid == nullptr) {
52 LOG_WARNING(CheatEngine, "Attempted to read input state, but hid is not initialized!");
53 return 0;
54 }
55
56 const auto applet_resource = hid->GetAppletResource();
52 if (applet_resource == nullptr) { 57 if (applet_resource == nullptr) {
53 LOG_WARNING(CheatEngine, 58 LOG_WARNING(CheatEngine,
54 "Attempted to read input state, but applet resource is not initialized!"); 59 "Attempted to read input state, but applet resource is not initialized!");
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index 708ae17aa..004f2e57a 100644
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -17,10 +17,10 @@
17#include "common/settings.h" 17#include "common/settings.h"
18#include "core/arm/arm_interface.h" 18#include "core/arm/arm_interface.h"
19#include "core/core.h" 19#include "core/core.h"
20#include "core/hle/kernel/hle_ipc.h"
21#include "core/hle/kernel/k_page_table.h" 20#include "core/hle/kernel/k_page_table.h"
22#include "core/hle/kernel/k_process.h" 21#include "core/hle/kernel/k_process.h"
23#include "core/hle/result.h" 22#include "core/hle/result.h"
23#include "core/hle/service/hle_ipc.h"
24#include "core/memory.h" 24#include "core/memory.h"
25#include "core/reporter.h" 25#include "core/reporter.h"
26 26
@@ -170,7 +170,7 @@ json GetHLEBufferDescriptorData(const std::vector<DescriptorType>& buffer,
170 return buffer_out; 170 return buffer_out;
171} 171}
172 172
173json GetHLERequestContextData(Kernel::HLERequestContext& ctx, Core::Memory::Memory& memory) { 173json GetHLERequestContextData(Service::HLERequestContext& ctx, Core::Memory::Memory& memory) {
174 json out; 174 json out;
175 175
176 auto cmd_buf = json::array(); 176 auto cmd_buf = json::array();
@@ -253,7 +253,7 @@ void Reporter::SaveSvcBreakReport(u32 type, bool signal_debugger, u64 info1, u64
253 SaveToFile(out, GetPath("svc_break_report", title_id, timestamp)); 253 SaveToFile(out, GetPath("svc_break_report", title_id, timestamp));
254} 254}
255 255
256void Reporter::SaveUnimplementedFunctionReport(Kernel::HLERequestContext& ctx, u32 command_id, 256void Reporter::SaveUnimplementedFunctionReport(Service::HLERequestContext& ctx, u32 command_id,
257 const std::string& name, 257 const std::string& name,
258 const std::string& service_name) const { 258 const std::string& service_name) const {
259 if (!IsReportingEnabled()) { 259 if (!IsReportingEnabled()) {
diff --git a/src/core/reporter.h b/src/core/reporter.h
index bb11f8e7c..db1ca3ba0 100644
--- a/src/core/reporter.h
+++ b/src/core/reporter.h
@@ -12,9 +12,9 @@
12 12
13union Result; 13union Result;
14 14
15namespace Kernel { 15namespace Service {
16class HLERequestContext; 16class HLERequestContext;
17} // namespace Kernel 17} // namespace Service
18 18
19namespace Service::LM { 19namespace Service::LM {
20struct LogMessage; 20struct LogMessage;
@@ -40,7 +40,7 @@ public:
40 const std::optional<std::vector<u8>>& resolved_buffer = {}) const; 40 const std::optional<std::vector<u8>>& resolved_buffer = {}) const;
41 41
42 // Used by HLE service handler 42 // Used by HLE service handler
43 void SaveUnimplementedFunctionReport(Kernel::HLERequestContext& ctx, u32 command_id, 43 void SaveUnimplementedFunctionReport(Service::HLERequestContext& ctx, u32 command_id,
44 const std::string& name, 44 const std::string& name,
45 const std::string& service_name) const; 45 const std::string& service_name) const;
46 46
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index e3b627e4f..322c29065 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -89,7 +89,7 @@ if (ENABLE_LIBUSB)
89endif() 89endif()
90 90
91create_target_directory_groups(input_common) 91create_target_directory_groups(input_common)
92target_link_libraries(input_common PUBLIC core PRIVATE common Boost::boost) 92target_link_libraries(input_common PUBLIC core PRIVATE common Boost::headers)
93 93
94if (YUZU_USE_PRECOMPILED_HEADERS) 94if (YUZU_USE_PRECOMPILED_HEADERS)
95 target_precompile_headers(input_common PRIVATE precompiled_headers.h) 95 target_precompile_headers(input_common PRIVATE precompiled_headers.h)
diff --git a/src/input_common/drivers/joycon.cpp b/src/input_common/drivers/joycon.cpp
index b4cd39a20..8b57ebe07 100644
--- a/src/input_common/drivers/joycon.cpp
+++ b/src/input_common/drivers/joycon.cpp
@@ -307,8 +307,8 @@ Common::Input::DriverResult Joycons::SetPollingMode(const PadIdentifier& identif
307 switch (polling_mode) { 307 switch (polling_mode) {
308 case Common::Input::PollingMode::Active: 308 case Common::Input::PollingMode::Active:
309 return static_cast<Common::Input::DriverResult>(handle->SetActiveMode()); 309 return static_cast<Common::Input::DriverResult>(handle->SetActiveMode());
310 case Common::Input::PollingMode::Pasive: 310 case Common::Input::PollingMode::Passive:
311 return static_cast<Common::Input::DriverResult>(handle->SetPasiveMode()); 311 return static_cast<Common::Input::DriverResult>(handle->SetPassiveMode());
312 case Common::Input::PollingMode::IR: 312 case Common::Input::PollingMode::IR:
313 return static_cast<Common::Input::DriverResult>(handle->SetIrMode()); 313 return static_cast<Common::Input::DriverResult>(handle->SetIrMode());
314 case Common::Input::PollingMode::NFC: 314 case Common::Input::PollingMode::NFC:
diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp
index 8b7f9aee9..94e92c37d 100644
--- a/src/input_common/drivers/mouse.cpp
+++ b/src/input_common/drivers/mouse.cpp
@@ -3,6 +3,7 @@
3 3
4#include <thread> 4#include <thread>
5#include <fmt/format.h> 5#include <fmt/format.h>
6#include <math.h>
6 7
7#include "common/param_package.h" 8#include "common/param_package.h"
8#include "common/settings.h" 9#include "common/settings.h"
@@ -11,8 +12,9 @@
11 12
12namespace InputCommon { 13namespace InputCommon {
13constexpr int update_time = 10; 14constexpr int update_time = 10;
14constexpr float default_stick_sensitivity = 0.022f; 15constexpr float default_stick_sensitivity = 0.0044f;
15constexpr float default_motion_sensitivity = 0.008f; 16constexpr float default_motion_sensitivity = 0.0003f;
17constexpr float maximum_rotation_speed = 2.0f;
16constexpr int mouse_axis_x = 0; 18constexpr int mouse_axis_x = 0;
17constexpr int mouse_axis_y = 1; 19constexpr int mouse_axis_y = 1;
18constexpr int wheel_axis_x = 2; 20constexpr int wheel_axis_x = 2;
@@ -99,11 +101,13 @@ void Mouse::UpdateMotionInput() {
99 const float sensitivity = 101 const float sensitivity =
100 Settings::values.mouse_panning_sensitivity.GetValue() * default_motion_sensitivity; 102 Settings::values.mouse_panning_sensitivity.GetValue() * default_motion_sensitivity;
101 103
102 // Slow movement by 7% 104 const float rotation_velocity = std::sqrt(last_motion_change.x * last_motion_change.x +
103 if (Settings::values.mouse_panning) { 105 last_motion_change.y * last_motion_change.y);
104 last_motion_change *= 0.93f; 106
105 } else { 107 if (rotation_velocity > maximum_rotation_speed / sensitivity) {
106 last_motion_change.z *= 0.93f; 108 const float multiplier = maximum_rotation_speed / rotation_velocity / sensitivity;
109 last_motion_change.x = last_motion_change.x * multiplier;
110 last_motion_change.y = last_motion_change.y * multiplier;
107 } 111 }
108 112
109 const BasicMotion motion_data{ 113 const BasicMotion motion_data{
@@ -116,6 +120,12 @@ void Mouse::UpdateMotionInput() {
116 .delta_timestamp = update_time * 1000, 120 .delta_timestamp = update_time * 1000,
117 }; 121 };
118 122
123 if (Settings::values.mouse_panning) {
124 last_motion_change.x = 0;
125 last_motion_change.y = 0;
126 }
127 last_motion_change.z = 0;
128
119 SetMotion(motion_identifier, 0, motion_data); 129 SetMotion(motion_identifier, 0, motion_data);
120} 130}
121 131
@@ -125,7 +135,7 @@ void Mouse::Move(int x, int y, int center_x, int center_y) {
125 135
126 auto mouse_change = 136 auto mouse_change =
127 (Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>(); 137 (Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>();
128 Common::Vec3<float> motion_change{-mouse_change.y, -mouse_change.x, last_motion_change.z}; 138 last_motion_change += {-mouse_change.y, -mouse_change.x, last_motion_change.z};
129 139
130 const auto move_distance = mouse_change.Length(); 140 const auto move_distance = mouse_change.Length();
131 if (move_distance == 0) { 141 if (move_distance == 0) {
@@ -141,7 +151,6 @@ void Mouse::Move(int x, int y, int center_x, int center_y) {
141 151
142 // Average mouse movements 152 // Average mouse movements
143 last_mouse_change = (last_mouse_change * 0.91f) + (mouse_change * 0.09f); 153 last_mouse_change = (last_mouse_change * 0.91f) + (mouse_change * 0.09f);
144 last_motion_change = (last_motion_change * 0.69f) + (motion_change * 0.31f);
145 154
146 const auto last_move_distance = last_mouse_change.Length(); 155 const auto last_move_distance = last_mouse_change.Length();
147 156
diff --git a/src/input_common/drivers/virtual_amiibo.h b/src/input_common/drivers/virtual_amiibo.h
index 13cacfc0a..488d00b31 100644
--- a/src/input_common/drivers/virtual_amiibo.h
+++ b/src/input_common/drivers/virtual_amiibo.h
@@ -60,6 +60,6 @@ private:
60 std::string file_path{}; 60 std::string file_path{};
61 State state{State::Initialized}; 61 State state{State::Initialized};
62 std::vector<u8> nfc_data; 62 std::vector<u8> nfc_data;
63 Common::Input::PollingMode polling_mode{Common::Input::PollingMode::Pasive}; 63 Common::Input::PollingMode polling_mode{Common::Input::PollingMode::Passive};
64}; 64};
65} // namespace InputCommon 65} // namespace InputCommon
diff --git a/src/input_common/helpers/joycon_driver.cpp b/src/input_common/helpers/joycon_driver.cpp
index e65b6b845..78cc5893c 100644
--- a/src/input_common/helpers/joycon_driver.cpp
+++ b/src/input_common/helpers/joycon_driver.cpp
@@ -410,7 +410,7 @@ DriverResult JoyconDriver::SetIrsConfig(IrsMode mode_, IrsResolution format_) {
410 return result; 410 return result;
411} 411}
412 412
413DriverResult JoyconDriver::SetPasiveMode() { 413DriverResult JoyconDriver::SetPassiveMode() {
414 std::scoped_lock lock{mutex}; 414 std::scoped_lock lock{mutex};
415 motion_enabled = false; 415 motion_enabled = false;
416 hidbus_enabled = false; 416 hidbus_enabled = false;
diff --git a/src/input_common/helpers/joycon_driver.h b/src/input_common/helpers/joycon_driver.h
index c1e189fa5..b52a13ecf 100644
--- a/src/input_common/helpers/joycon_driver.h
+++ b/src/input_common/helpers/joycon_driver.h
@@ -44,7 +44,7 @@ public:
44 DriverResult SetVibration(const VibrationValue& vibration); 44 DriverResult SetVibration(const VibrationValue& vibration);
45 DriverResult SetLedConfig(u8 led_pattern); 45 DriverResult SetLedConfig(u8 led_pattern);
46 DriverResult SetIrsConfig(IrsMode mode_, IrsResolution format_); 46 DriverResult SetIrsConfig(IrsMode mode_, IrsResolution format_);
47 DriverResult SetPasiveMode(); 47 DriverResult SetPassiveMode();
48 DriverResult SetActiveMode(); 48 DriverResult SetActiveMode();
49 DriverResult SetIrMode(); 49 DriverResult SetIrMode();
50 DriverResult SetNfcMode(); 50 DriverResult SetNfcMode();
diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h
index b91934990..dcac0e422 100644
--- a/src/input_common/helpers/joycon_protocol/joycon_types.h
+++ b/src/input_common/helpers/joycon_protocol/joycon_types.h
@@ -78,7 +78,7 @@ enum class PadButton : u32 {
78 Capture = 0x200000, 78 Capture = 0x200000,
79}; 79};
80 80
81enum class PasivePadButton : u32 { 81enum class PassivePadButton : u32 {
82 Down_A = 0x0001, 82 Down_A = 0x0001,
83 Right_X = 0x0002, 83 Right_X = 0x0002,
84 Left_B = 0x0004, 84 Left_B = 0x0004,
@@ -95,6 +95,18 @@ enum class PasivePadButton : u32 {
95 ZL_ZR = 0x8000, 95 ZL_ZR = 0x8000,
96}; 96};
97 97
98enum class PassivePadStick : u8 {
99 Right = 0x00,
100 RightDown = 0x01,
101 Down = 0x02,
102 DownLeft = 0x03,
103 Left = 0x04,
104 LeftUp = 0x05,
105 Up = 0x06,
106 UpRight = 0x07,
107 Neutral = 0x08,
108};
109
98enum class OutputReport : u8 { 110enum class OutputReport : u8 {
99 RUMBLE_AND_SUBCMD = 0x01, 111 RUMBLE_AND_SUBCMD = 0x01,
100 FW_UPDATE_PKT = 0x03, 112 FW_UPDATE_PKT = 0x03,
diff --git a/src/input_common/helpers/joycon_protocol/poller.cpp b/src/input_common/helpers/joycon_protocol/poller.cpp
index 9bb15e935..dca797f7a 100644
--- a/src/input_common/helpers/joycon_protocol/poller.cpp
+++ b/src/input_common/helpers/joycon_protocol/poller.cpp
@@ -12,7 +12,7 @@ JoyconPoller::JoyconPoller(ControllerType device_type_, JoyStickCalibration left
12 : device_type{device_type_}, left_stick_calibration{left_stick_calibration_}, 12 : device_type{device_type_}, left_stick_calibration{left_stick_calibration_},
13 right_stick_calibration{right_stick_calibration_}, motion_calibration{motion_calibration_} {} 13 right_stick_calibration{right_stick_calibration_}, motion_calibration{motion_calibration_} {}
14 14
15void JoyconPoller::SetCallbacks(const Joycon::JoyconCallbacks& callbacks_) { 15void JoyconPoller::SetCallbacks(const JoyconCallbacks& callbacks_) {
16 callbacks = std::move(callbacks_); 16 callbacks = std::move(callbacks_);
17} 17}
18 18
@@ -22,13 +22,13 @@ void JoyconPoller::ReadActiveMode(std::span<u8> buffer, const MotionStatus& moti
22 memcpy(&data, buffer.data(), sizeof(InputReportActive)); 22 memcpy(&data, buffer.data(), sizeof(InputReportActive));
23 23
24 switch (device_type) { 24 switch (device_type) {
25 case Joycon::ControllerType::Left: 25 case ControllerType::Left:
26 UpdateActiveLeftPadInput(data, motion_status); 26 UpdateActiveLeftPadInput(data, motion_status);
27 break; 27 break;
28 case Joycon::ControllerType::Right: 28 case ControllerType::Right:
29 UpdateActiveRightPadInput(data, motion_status); 29 UpdateActiveRightPadInput(data, motion_status);
30 break; 30 break;
31 case Joycon::ControllerType::Pro: 31 case ControllerType::Pro:
32 UpdateActiveProPadInput(data, motion_status); 32 UpdateActiveProPadInput(data, motion_status);
33 break; 33 break;
34 default: 34 default:
@@ -47,14 +47,14 @@ void JoyconPoller::ReadPassiveMode(std::span<u8> buffer) {
47 memcpy(&data, buffer.data(), sizeof(InputReportPassive)); 47 memcpy(&data, buffer.data(), sizeof(InputReportPassive));
48 48
49 switch (device_type) { 49 switch (device_type) {
50 case Joycon::ControllerType::Left: 50 case ControllerType::Left:
51 UpdatePasiveLeftPadInput(data); 51 UpdatePassiveLeftPadInput(data);
52 break; 52 break;
53 case Joycon::ControllerType::Right: 53 case ControllerType::Right:
54 UpdatePasiveRightPadInput(data); 54 UpdatePassiveRightPadInput(data);
55 break; 55 break;
56 case Joycon::ControllerType::Pro: 56 case ControllerType::Pro:
57 UpdatePasiveProPadInput(data); 57 UpdatePassiveProPadInput(data);
58 break; 58 break;
59 default: 59 default:
60 break; 60 break;
@@ -210,14 +210,12 @@ void JoyconPoller::UpdateActiveProPadInput(const InputReportActive& input,
210 } 210 }
211} 211}
212 212
213void JoyconPoller::UpdatePasiveLeftPadInput(const InputReportPassive& input) { 213void JoyconPoller::UpdatePassiveLeftPadInput(const InputReportPassive& input) {
214 static constexpr std::array<Joycon::PasivePadButton, 11> left_buttons{ 214 static constexpr std::array<PassivePadButton, 11> left_buttons{
215 Joycon::PasivePadButton::Down_A, Joycon::PasivePadButton::Right_X, 215 PassivePadButton::Down_A, PassivePadButton::Right_X, PassivePadButton::Left_B,
216 Joycon::PasivePadButton::Left_B, Joycon::PasivePadButton::Up_Y, 216 PassivePadButton::Up_Y, PassivePadButton::SL, PassivePadButton::SR,
217 Joycon::PasivePadButton::SL, Joycon::PasivePadButton::SR, 217 PassivePadButton::L_R, PassivePadButton::ZL_ZR, PassivePadButton::Minus,
218 Joycon::PasivePadButton::L_R, Joycon::PasivePadButton::ZL_ZR, 218 PassivePadButton::Capture, PassivePadButton::StickL,
219 Joycon::PasivePadButton::Minus, Joycon::PasivePadButton::Capture,
220 Joycon::PasivePadButton::StickL,
221 }; 219 };
222 220
223 for (auto left_button : left_buttons) { 221 for (auto left_button : left_buttons) {
@@ -225,16 +223,19 @@ void JoyconPoller::UpdatePasiveLeftPadInput(const InputReportPassive& input) {
225 const int button = static_cast<int>(left_button); 223 const int button = static_cast<int>(left_button);
226 callbacks.on_button_data(button, button_status); 224 callbacks.on_button_data(button, button_status);
227 } 225 }
226
227 const auto [left_axis_x, left_axis_y] =
228 GetPassiveAxisValue(static_cast<PassivePadStick>(input.stick_state));
229 callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickX), left_axis_x);
230 callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickY), left_axis_y);
228} 231}
229 232
230void JoyconPoller::UpdatePasiveRightPadInput(const InputReportPassive& input) { 233void JoyconPoller::UpdatePassiveRightPadInput(const InputReportPassive& input) {
231 static constexpr std::array<Joycon::PasivePadButton, 11> right_buttons{ 234 static constexpr std::array<PassivePadButton, 11> right_buttons{
232 Joycon::PasivePadButton::Down_A, Joycon::PasivePadButton::Right_X, 235 PassivePadButton::Down_A, PassivePadButton::Right_X, PassivePadButton::Left_B,
233 Joycon::PasivePadButton::Left_B, Joycon::PasivePadButton::Up_Y, 236 PassivePadButton::Up_Y, PassivePadButton::SL, PassivePadButton::SR,
234 Joycon::PasivePadButton::SL, Joycon::PasivePadButton::SR, 237 PassivePadButton::L_R, PassivePadButton::ZL_ZR, PassivePadButton::Plus,
235 Joycon::PasivePadButton::L_R, Joycon::PasivePadButton::ZL_ZR, 238 PassivePadButton::Home, PassivePadButton::StickR,
236 Joycon::PasivePadButton::Plus, Joycon::PasivePadButton::Home,
237 Joycon::PasivePadButton::StickR,
238 }; 239 };
239 240
240 for (auto right_button : right_buttons) { 241 for (auto right_button : right_buttons) {
@@ -242,17 +243,20 @@ void JoyconPoller::UpdatePasiveRightPadInput(const InputReportPassive& input) {
242 const int button = static_cast<int>(right_button); 243 const int button = static_cast<int>(right_button);
243 callbacks.on_button_data(button, button_status); 244 callbacks.on_button_data(button, button_status);
244 } 245 }
246
247 const auto [right_axis_x, right_axis_y] =
248 GetPassiveAxisValue(static_cast<PassivePadStick>(input.stick_state));
249 callbacks.on_stick_data(static_cast<int>(PadAxes::RightStickX), right_axis_x);
250 callbacks.on_stick_data(static_cast<int>(PadAxes::RightStickY), right_axis_y);
245} 251}
246 252
247void JoyconPoller::UpdatePasiveProPadInput(const InputReportPassive& input) { 253void JoyconPoller::UpdatePassiveProPadInput(const InputReportPassive& input) {
248 static constexpr std::array<Joycon::PasivePadButton, 14> pro_buttons{ 254 static constexpr std::array<PassivePadButton, 14> pro_buttons{
249 Joycon::PasivePadButton::Down_A, Joycon::PasivePadButton::Right_X, 255 PassivePadButton::Down_A, PassivePadButton::Right_X, PassivePadButton::Left_B,
250 Joycon::PasivePadButton::Left_B, Joycon::PasivePadButton::Up_Y, 256 PassivePadButton::Up_Y, PassivePadButton::SL, PassivePadButton::SR,
251 Joycon::PasivePadButton::SL, Joycon::PasivePadButton::SR, 257 PassivePadButton::L_R, PassivePadButton::ZL_ZR, PassivePadButton::Minus,
252 Joycon::PasivePadButton::L_R, Joycon::PasivePadButton::ZL_ZR, 258 PassivePadButton::Plus, PassivePadButton::Capture, PassivePadButton::Home,
253 Joycon::PasivePadButton::Minus, Joycon::PasivePadButton::Plus, 259 PassivePadButton::StickL, PassivePadButton::StickR,
254 Joycon::PasivePadButton::Capture, Joycon::PasivePadButton::Home,
255 Joycon::PasivePadButton::StickL, Joycon::PasivePadButton::StickR,
256 }; 260 };
257 261
258 for (auto pro_button : pro_buttons) { 262 for (auto pro_button : pro_buttons) {
@@ -260,6 +264,15 @@ void JoyconPoller::UpdatePasiveProPadInput(const InputReportPassive& input) {
260 const int button = static_cast<int>(pro_button); 264 const int button = static_cast<int>(pro_button);
261 callbacks.on_button_data(button, button_status); 265 callbacks.on_button_data(button, button_status);
262 } 266 }
267
268 const auto [left_axis_x, left_axis_y] =
269 GetPassiveAxisValue(static_cast<PassivePadStick>(input.stick_state & 0xf));
270 const auto [right_axis_x, right_axis_y] =
271 GetPassiveAxisValue(static_cast<PassivePadStick>(input.stick_state >> 4));
272 callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickX), left_axis_x);
273 callbacks.on_stick_data(static_cast<int>(PadAxes::LeftStickY), left_axis_y);
274 callbacks.on_stick_data(static_cast<int>(PadAxes::RightStickX), right_axis_x);
275 callbacks.on_stick_data(static_cast<int>(PadAxes::RightStickY), right_axis_y);
263} 276}
264 277
265f32 JoyconPoller::GetAxisValue(u16 raw_value, Joycon::JoyStickAxisCalibration calibration) const { 278f32 JoyconPoller::GetAxisValue(u16 raw_value, Joycon::JoyStickAxisCalibration calibration) const {
@@ -270,6 +283,30 @@ f32 JoyconPoller::GetAxisValue(u16 raw_value, Joycon::JoyStickAxisCalibration ca
270 return value / calibration.min; 283 return value / calibration.min;
271} 284}
272 285
286std::pair<f32, f32> JoyconPoller::GetPassiveAxisValue(PassivePadStick raw_value) const {
287 switch (raw_value) {
288 case PassivePadStick::Right:
289 return {1.0f, 0.0f};
290 case PassivePadStick::RightDown:
291 return {1.0f, -1.0f};
292 case PassivePadStick::Down:
293 return {0.0f, -1.0f};
294 case PassivePadStick::DownLeft:
295 return {-1.0f, -1.0f};
296 case PassivePadStick::Left:
297 return {-1.0f, 0.0f};
298 case PassivePadStick::LeftUp:
299 return {-1.0f, 1.0f};
300 case PassivePadStick::Up:
301 return {0.0f, 1.0f};
302 case PassivePadStick::UpRight:
303 return {1.0f, 1.0f};
304 case PassivePadStick::Neutral:
305 default:
306 return {0.0f, 0.0f};
307 }
308}
309
273f32 JoyconPoller::GetAccelerometerValue(s16 raw, const MotionSensorCalibration& cal, 310f32 JoyconPoller::GetAccelerometerValue(s16 raw, const MotionSensorCalibration& cal,
274 AccelerometerSensitivity sensitivity) const { 311 AccelerometerSensitivity sensitivity) const {
275 const f32 value = raw * (1.0f / (cal.scale - cal.offset)) * 4; 312 const f32 value = raw * (1.0f / (cal.scale - cal.offset)) * 4;
diff --git a/src/input_common/helpers/joycon_protocol/poller.h b/src/input_common/helpers/joycon_protocol/poller.h
index 354d41dad..0fa72c6db 100644
--- a/src/input_common/helpers/joycon_protocol/poller.h
+++ b/src/input_common/helpers/joycon_protocol/poller.h
@@ -22,7 +22,7 @@ public:
22 JoyStickCalibration right_stick_calibration_, 22 JoyStickCalibration right_stick_calibration_,
23 MotionCalibration motion_calibration_); 23 MotionCalibration motion_calibration_);
24 24
25 void SetCallbacks(const Joycon::JoyconCallbacks& callbacks_); 25 void SetCallbacks(const JoyconCallbacks& callbacks_);
26 26
27 /// Handles data from passive packages 27 /// Handles data from passive packages
28 void ReadPassiveMode(std::span<u8> buffer); 28 void ReadPassiveMode(std::span<u8> buffer);
@@ -46,12 +46,15 @@ private:
46 const MotionStatus& motion_status); 46 const MotionStatus& motion_status);
47 void UpdateActiveProPadInput(const InputReportActive& input, const MotionStatus& motion_status); 47 void UpdateActiveProPadInput(const InputReportActive& input, const MotionStatus& motion_status);
48 48
49 void UpdatePasiveLeftPadInput(const InputReportPassive& buffer); 49 void UpdatePassiveLeftPadInput(const InputReportPassive& buffer);
50 void UpdatePasiveRightPadInput(const InputReportPassive& buffer); 50 void UpdatePassiveRightPadInput(const InputReportPassive& buffer);
51 void UpdatePasiveProPadInput(const InputReportPassive& buffer); 51 void UpdatePassiveProPadInput(const InputReportPassive& buffer);
52 52
53 /// Returns a calibrated joystick axis from raw axis data 53 /// Returns a calibrated joystick axis from raw axis data
54 f32 GetAxisValue(u16 raw_value, Joycon::JoyStickAxisCalibration calibration) const; 54 f32 GetAxisValue(u16 raw_value, JoyStickAxisCalibration calibration) const;
55
56 /// Returns a digital joystick axis from passive axis data
57 std::pair<f32, f32> GetPassiveAxisValue(PassivePadStick raw_value) const;
55 58
56 /// Returns a calibrated accelerometer axis from raw motion data 59 /// Returns a calibrated accelerometer axis from raw motion data
57 f32 GetAccelerometerValue(s16 raw, const MotionSensorCalibration& cal, 60 f32 GetAccelerometerValue(s16 raw, const MotionSensorCalibration& cal,
@@ -75,7 +78,7 @@ private:
75 JoyStickCalibration right_stick_calibration{}; 78 JoyStickCalibration right_stick_calibration{};
76 MotionCalibration motion_calibration{}; 79 MotionCalibration motion_calibration{};
77 80
78 Joycon::JoyconCallbacks callbacks{}; 81 JoyconCallbacks callbacks{};
79}; 82};
80 83
81} // namespace InputCommon::Joycon 84} // namespace InputCommon::Joycon
diff --git a/src/input_common/input_mapping.cpp b/src/input_common/input_mapping.cpp
index 2ff480ff9..9361b00c5 100644
--- a/src/input_common/input_mapping.cpp
+++ b/src/input_common/input_mapping.cpp
@@ -146,6 +146,7 @@ void MappingFactory::RegisterMotion(const MappingData& data) {
146 if (data.engine == "mouse") { 146 if (data.engine == "mouse") {
147 new_input.Set("motion", 0); 147 new_input.Set("motion", 0);
148 new_input.Set("pad", 1); 148 new_input.Set("pad", 1);
149 new_input.Set("threshold", 0.001f);
149 input_queue.Push(new_input); 150 input_queue.Push(new_input);
150 return; 151 return;
151 } 152 }
diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt
index 1ab52da59..8e306219f 100644
--- a/src/network/CMakeLists.txt
+++ b/src/network/CMakeLists.txt
@@ -19,7 +19,7 @@ add_library(network STATIC
19 19
20create_target_directory_groups(network) 20create_target_directory_groups(network)
21 21
22target_link_libraries(network PRIVATE common enet::enet Boost::boost) 22target_link_libraries(network PRIVATE common enet::enet Boost::headers)
23if (ENABLE_WEB_SERVICE) 23if (ENABLE_WEB_SERVICE)
24 target_compile_definitions(network PRIVATE -DENABLE_WEB_SERVICE) 24 target_compile_definitions(network PRIVATE -DENABLE_WEB_SERVICE)
25 target_link_libraries(network PRIVATE web_service) 25 target_link_libraries(network PRIVATE web_service)
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 4742bcbe9..e904573d7 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -330,3 +330,7 @@ endif()
330if (YUZU_USE_PRECOMPILED_HEADERS) 330if (YUZU_USE_PRECOMPILED_HEADERS)
331 target_precompile_headers(video_core PRIVATE precompiled_headers.h) 331 target_precompile_headers(video_core PRIVATE precompiled_headers.h)
332endif() 332endif()
333
334if (YUZU_ENABLE_LTO)
335 set_property(TARGET video_core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
336endif()
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 20faa65da..1f656ffa8 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -55,6 +55,19 @@ constexpr u32 NUM_STORAGE_BUFFERS = 16;
55constexpr u32 NUM_TEXTURE_BUFFERS = 16; 55constexpr u32 NUM_TEXTURE_BUFFERS = 16;
56constexpr u32 NUM_STAGES = 5; 56constexpr u32 NUM_STAGES = 5;
57 57
58enum class ObtainBufferSynchronize : u32 {
59 NoSynchronize = 0,
60 FullSynchronize = 1,
61 SynchronizeNoDirty = 2,
62};
63
64enum class ObtainBufferOperation : u32 {
65 DoNothing = 0,
66 MarkAsWritten = 1,
67 DiscardWrite = 2,
68 MarkQuery = 3,
69};
70
58using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>; 71using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>;
59using ComputeUniformBufferSizes = std::array<u32, NUM_COMPUTE_UNIFORM_BUFFERS>; 72using ComputeUniformBufferSizes = std::array<u32, NUM_COMPUTE_UNIFORM_BUFFERS>;
60 73
@@ -191,6 +204,10 @@ public:
191 204
192 bool DMAClear(GPUVAddr src_address, u64 amount, u32 value); 205 bool DMAClear(GPUVAddr src_address, u64 amount, u32 value);
193 206
207 [[nodiscard]] std::pair<Buffer*, u32> ObtainBuffer(GPUVAddr gpu_addr, u32 size,
208 ObtainBufferSynchronize sync_info,
209 ObtainBufferOperation post_op);
210
194 /// Return true when a CPU region is modified from the GPU 211 /// Return true when a CPU region is modified from the GPU
195 [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); 212 [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size);
196 213
@@ -643,6 +660,42 @@ bool BufferCache<P>::DMAClear(GPUVAddr dst_address, u64 amount, u32 value) {
643} 660}
644 661
645template <class P> 662template <class P>
663std::pair<typename P::Buffer*, u32> BufferCache<P>::ObtainBuffer(GPUVAddr gpu_addr, u32 size,
664 ObtainBufferSynchronize sync_info,
665 ObtainBufferOperation post_op) {
666 const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
667 if (!cpu_addr) {
668 return {&slot_buffers[NULL_BUFFER_ID], 0};
669 }
670 const BufferId buffer_id = FindBuffer(*cpu_addr, size);
671 Buffer& buffer = slot_buffers[buffer_id];
672
673 // synchronize op
674 switch (sync_info) {
675 case ObtainBufferSynchronize::FullSynchronize:
676 SynchronizeBuffer(buffer, *cpu_addr, size);
677 break;
678 default:
679 break;
680 }
681
682 switch (post_op) {
683 case ObtainBufferOperation::MarkAsWritten:
684 MarkWrittenBuffer(buffer_id, *cpu_addr, size);
685 break;
686 case ObtainBufferOperation::DiscardWrite: {
687 IntervalType interval{*cpu_addr, size};
688 ClearDownload(interval);
689 break;
690 }
691 default:
692 break;
693 }
694
695 return {&buffer, buffer.Offset(*cpu_addr)};
696}
697
698template <class P>
646void BufferCache<P>::BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, 699void BufferCache<P>::BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr,
647 u32 size) { 700 u32 size) {
648 const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); 701 const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index 7762c7d96..e68850dc5 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -14,7 +14,13 @@
14#include "video_core/textures/decoders.h" 14#include "video_core/textures/decoders.h"
15 15
16MICROPROFILE_DECLARE(GPU_DMAEngine); 16MICROPROFILE_DECLARE(GPU_DMAEngine);
17MICROPROFILE_DECLARE(GPU_DMAEngineBL);
18MICROPROFILE_DECLARE(GPU_DMAEngineLB);
19MICROPROFILE_DECLARE(GPU_DMAEngineBB);
17MICROPROFILE_DEFINE(GPU_DMAEngine, "GPU", "DMA Engine", MP_RGB(224, 224, 128)); 20MICROPROFILE_DEFINE(GPU_DMAEngine, "GPU", "DMA Engine", MP_RGB(224, 224, 128));
21MICROPROFILE_DEFINE(GPU_DMAEngineBL, "GPU", "DMA Engine Block - Linear", MP_RGB(224, 224, 128));
22MICROPROFILE_DEFINE(GPU_DMAEngineLB, "GPU", "DMA Engine Linear - Block", MP_RGB(224, 224, 128));
23MICROPROFILE_DEFINE(GPU_DMAEngineBB, "GPU", "DMA Engine Block - Block", MP_RGB(224, 224, 128));
18 24
19namespace Tegra::Engines { 25namespace Tegra::Engines {
20 26
@@ -72,6 +78,7 @@ void MaxwellDMA::Launch() {
72 memory_manager.FlushCaching(); 78 memory_manager.FlushCaching();
73 if (!is_src_pitch && !is_dst_pitch) { 79 if (!is_src_pitch && !is_dst_pitch) {
74 // If both the source and the destination are in block layout, assert. 80 // If both the source and the destination are in block layout, assert.
81 MICROPROFILE_SCOPE(GPU_DMAEngineBB);
75 CopyBlockLinearToBlockLinear(); 82 CopyBlockLinearToBlockLinear();
76 ReleaseSemaphore(); 83 ReleaseSemaphore();
77 return; 84 return;
@@ -87,8 +94,10 @@ void MaxwellDMA::Launch() {
87 } 94 }
88 } else { 95 } else {
89 if (!is_src_pitch && is_dst_pitch) { 96 if (!is_src_pitch && is_dst_pitch) {
97 MICROPROFILE_SCOPE(GPU_DMAEngineBL);
90 CopyBlockLinearToPitch(); 98 CopyBlockLinearToPitch();
91 } else { 99 } else {
100 MICROPROFILE_SCOPE(GPU_DMAEngineLB);
92 CopyPitchToBlockLinear(); 101 CopyPitchToBlockLinear();
93 } 102 }
94 } 103 }
@@ -153,21 +162,35 @@ void MaxwellDMA::Launch() {
153} 162}
154 163
155void MaxwellDMA::CopyBlockLinearToPitch() { 164void MaxwellDMA::CopyBlockLinearToPitch() {
156 UNIMPLEMENTED_IF(regs.src_params.block_size.width != 0); 165 UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0);
157 UNIMPLEMENTED_IF(regs.src_params.layer != 0); 166
158 167 u32 bytes_per_pixel = 1;
159 const bool is_remapping = regs.launch_dma.remap_enable != 0; 168 DMA::ImageOperand src_operand;
160 169 src_operand.bytes_per_pixel = bytes_per_pixel;
161 // Optimized path for micro copies. 170 src_operand.params = regs.src_params;
162 const size_t dst_size = static_cast<size_t>(regs.pitch_out) * regs.line_count; 171 src_operand.address = regs.offset_in;
163 if (!is_remapping && dst_size < GOB_SIZE && regs.pitch_out <= GOB_SIZE_X && 172
164 regs.src_params.height > GOB_SIZE_Y) { 173 DMA::BufferOperand dst_operand;
165 FastCopyBlockLinearToPitch(); 174 dst_operand.pitch = regs.pitch_out;
175 dst_operand.width = regs.line_length_in;
176 dst_operand.height = regs.line_count;
177 dst_operand.address = regs.offset_out;
178 DMA::ImageCopy copy_info{};
179 copy_info.length_x = regs.line_length_in;
180 copy_info.length_y = regs.line_count;
181 auto& accelerate = rasterizer->AccessAccelerateDMA();
182 if (accelerate.ImageToBuffer(copy_info, src_operand, dst_operand)) {
166 return; 183 return;
167 } 184 }
168 185
186 UNIMPLEMENTED_IF(regs.src_params.block_size.width != 0);
187 UNIMPLEMENTED_IF(regs.src_params.block_size.depth != 0);
188 UNIMPLEMENTED_IF(regs.src_params.block_size.depth == 0 && regs.src_params.depth != 1);
189
169 // Deswizzle the input and copy it over. 190 // Deswizzle the input and copy it over.
170 const Parameters& src_params = regs.src_params; 191 const DMA::Parameters& src_params = regs.src_params;
192
193 const bool is_remapping = regs.launch_dma.remap_enable != 0;
171 194
172 const u32 num_remap_components = regs.remap_const.num_dst_components_minus_one + 1; 195 const u32 num_remap_components = regs.remap_const.num_dst_components_minus_one + 1;
173 const u32 remap_components_size = regs.remap_const.component_size_minus_one + 1; 196 const u32 remap_components_size = regs.remap_const.component_size_minus_one + 1;
@@ -187,7 +210,7 @@ void MaxwellDMA::CopyBlockLinearToPitch() {
187 x_offset >>= bpp_shift; 210 x_offset >>= bpp_shift;
188 } 211 }
189 212
190 const u32 bytes_per_pixel = base_bpp << bpp_shift; 213 bytes_per_pixel = base_bpp << bpp_shift;
191 const u32 height = src_params.height; 214 const u32 height = src_params.height;
192 const u32 depth = src_params.depth; 215 const u32 depth = src_params.depth;
193 const u32 block_height = src_params.block_size.height; 216 const u32 block_height = src_params.block_size.height;
@@ -195,11 +218,12 @@ void MaxwellDMA::CopyBlockLinearToPitch() {
195 const size_t src_size = 218 const size_t src_size =
196 CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth); 219 CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth);
197 220
221 const size_t dst_size = static_cast<size_t>(regs.pitch_out) * regs.line_count;
198 read_buffer.resize_destructive(src_size); 222 read_buffer.resize_destructive(src_size);
199 write_buffer.resize_destructive(dst_size); 223 write_buffer.resize_destructive(dst_size);
200 224
201 memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size); 225 memory_manager.ReadBlock(src_operand.address, read_buffer.data(), src_size);
202 memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size); 226 memory_manager.ReadBlockUnsafe(dst_operand.address, write_buffer.data(), dst_size);
203 227
204 UnswizzleSubrect(write_buffer, read_buffer, bytes_per_pixel, width, height, depth, x_offset, 228 UnswizzleSubrect(write_buffer, read_buffer, bytes_per_pixel, width, height, depth, x_offset,
205 src_params.origin.y, x_elements, regs.line_count, block_height, block_depth, 229 src_params.origin.y, x_elements, regs.line_count, block_height, block_depth,
@@ -216,6 +240,24 @@ void MaxwellDMA::CopyPitchToBlockLinear() {
216 const u32 num_remap_components = regs.remap_const.num_dst_components_minus_one + 1; 240 const u32 num_remap_components = regs.remap_const.num_dst_components_minus_one + 1;
217 const u32 remap_components_size = regs.remap_const.component_size_minus_one + 1; 241 const u32 remap_components_size = regs.remap_const.component_size_minus_one + 1;
218 242
243 u32 bytes_per_pixel = 1;
244 DMA::ImageOperand dst_operand;
245 dst_operand.bytes_per_pixel = bytes_per_pixel;
246 dst_operand.params = regs.dst_params;
247 dst_operand.address = regs.offset_out;
248 DMA::BufferOperand src_operand;
249 src_operand.pitch = regs.pitch_in;
250 src_operand.width = regs.line_length_in;
251 src_operand.height = regs.line_count;
252 src_operand.address = regs.offset_in;
253 DMA::ImageCopy copy_info{};
254 copy_info.length_x = regs.line_length_in;
255 copy_info.length_y = regs.line_count;
256 auto& accelerate = rasterizer->AccessAccelerateDMA();
257 if (accelerate.BufferToImage(copy_info, src_operand, dst_operand)) {
258 return;
259 }
260
219 const auto& dst_params = regs.dst_params; 261 const auto& dst_params = regs.dst_params;
220 262
221 const u32 base_bpp = !is_remapping ? 1U : num_remap_components * remap_components_size; 263 const u32 base_bpp = !is_remapping ? 1U : num_remap_components * remap_components_size;
@@ -233,7 +275,7 @@ void MaxwellDMA::CopyPitchToBlockLinear() {
233 x_offset >>= bpp_shift; 275 x_offset >>= bpp_shift;
234 } 276 }
235 277
236 const u32 bytes_per_pixel = base_bpp << bpp_shift; 278 bytes_per_pixel = base_bpp << bpp_shift;
237 const u32 height = dst_params.height; 279 const u32 height = dst_params.height;
238 const u32 depth = dst_params.depth; 280 const u32 depth = dst_params.depth;
239 const u32 block_height = dst_params.block_size.height; 281 const u32 block_height = dst_params.block_size.height;
@@ -260,45 +302,14 @@ void MaxwellDMA::CopyPitchToBlockLinear() {
260 memory_manager.WriteBlockCached(regs.offset_out, write_buffer.data(), dst_size); 302 memory_manager.WriteBlockCached(regs.offset_out, write_buffer.data(), dst_size);
261} 303}
262 304
263void MaxwellDMA::FastCopyBlockLinearToPitch() {
264 const u32 bytes_per_pixel = 1U;
265 const size_t src_size = GOB_SIZE;
266 const size_t dst_size = static_cast<size_t>(regs.pitch_out) * regs.line_count;
267 u32 pos_x = regs.src_params.origin.x;
268 u32 pos_y = regs.src_params.origin.y;
269 const u64 offset = GetGOBOffset(regs.src_params.width, regs.src_params.height, pos_x, pos_y,
270 regs.src_params.block_size.height, bytes_per_pixel);
271 const u32 x_in_gob = 64 / bytes_per_pixel;
272 pos_x = pos_x % x_in_gob;
273 pos_y = pos_y % 8;
274
275 read_buffer.resize_destructive(src_size);
276 write_buffer.resize_destructive(dst_size);
277
278 if (Settings::IsGPULevelExtreme()) {
279 memory_manager.ReadBlock(regs.offset_in + offset, read_buffer.data(), src_size);
280 memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size);
281 } else {
282 memory_manager.ReadBlockUnsafe(regs.offset_in + offset, read_buffer.data(), src_size);
283 memory_manager.ReadBlockUnsafe(regs.offset_out, write_buffer.data(), dst_size);
284 }
285
286 UnswizzleSubrect(write_buffer, read_buffer, bytes_per_pixel, regs.src_params.width,
287 regs.src_params.height, 1, pos_x, pos_y, regs.line_length_in, regs.line_count,
288 regs.src_params.block_size.height, regs.src_params.block_size.depth,
289 regs.pitch_out);
290
291 memory_manager.WriteBlockCached(regs.offset_out, write_buffer.data(), dst_size);
292}
293
294void MaxwellDMA::CopyBlockLinearToBlockLinear() { 305void MaxwellDMA::CopyBlockLinearToBlockLinear() {
295 UNIMPLEMENTED_IF(regs.src_params.block_size.width != 0); 306 UNIMPLEMENTED_IF(regs.src_params.block_size.width != 0);
296 307
297 const bool is_remapping = regs.launch_dma.remap_enable != 0; 308 const bool is_remapping = regs.launch_dma.remap_enable != 0;
298 309
299 // Deswizzle the input and copy it over. 310 // Deswizzle the input and copy it over.
300 const Parameters& src = regs.src_params; 311 const DMA::Parameters& src = regs.src_params;
301 const Parameters& dst = regs.dst_params; 312 const DMA::Parameters& dst = regs.dst_params;
302 313
303 const u32 num_remap_components = regs.remap_const.num_dst_components_minus_one + 1; 314 const u32 num_remap_components = regs.remap_const.num_dst_components_minus_one + 1;
304 const u32 remap_components_size = regs.remap_const.component_size_minus_one + 1; 315 const u32 remap_components_size = regs.remap_const.component_size_minus_one + 1;
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h
index 0e594fa74..69e26cb32 100644
--- a/src/video_core/engines/maxwell_dma.h
+++ b/src/video_core/engines/maxwell_dma.h
@@ -24,6 +24,54 @@ namespace VideoCore {
24class RasterizerInterface; 24class RasterizerInterface;
25} 25}
26 26
27namespace Tegra {
28namespace DMA {
29
30union Origin {
31 BitField<0, 16, u32> x;
32 BitField<16, 16, u32> y;
33};
34static_assert(sizeof(Origin) == 4);
35
36struct ImageCopy {
37 u32 length_x{};
38 u32 length_y{};
39};
40
41union BlockSize {
42 BitField<0, 4, u32> width;
43 BitField<4, 4, u32> height;
44 BitField<8, 4, u32> depth;
45 BitField<12, 4, u32> gob_height;
46};
47static_assert(sizeof(BlockSize) == 4);
48
49struct Parameters {
50 BlockSize block_size;
51 u32 width;
52 u32 height;
53 u32 depth;
54 u32 layer;
55 Origin origin;
56};
57static_assert(sizeof(Parameters) == 24);
58
59struct ImageOperand {
60 u32 bytes_per_pixel;
61 Parameters params;
62 GPUVAddr address;
63};
64
65struct BufferOperand {
66 u32 pitch;
67 u32 width;
68 u32 height;
69 GPUVAddr address;
70};
71
72} // namespace DMA
73} // namespace Tegra
74
27namespace Tegra::Engines { 75namespace Tegra::Engines {
28 76
29class AccelerateDMAInterface { 77class AccelerateDMAInterface {
@@ -32,6 +80,12 @@ public:
32 virtual bool BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) = 0; 80 virtual bool BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) = 0;
33 81
34 virtual bool BufferClear(GPUVAddr src_address, u64 amount, u32 value) = 0; 82 virtual bool BufferClear(GPUVAddr src_address, u64 amount, u32 value) = 0;
83
84 virtual bool ImageToBuffer(const DMA::ImageCopy& copy_info, const DMA::ImageOperand& src,
85 const DMA::BufferOperand& dst) = 0;
86
87 virtual bool BufferToImage(const DMA::ImageCopy& copy_info, const DMA::BufferOperand& src,
88 const DMA::ImageOperand& dst) = 0;
35}; 89};
36 90
37/** 91/**
@@ -51,30 +105,6 @@ public:
51 } 105 }
52 }; 106 };
53 107
54 union BlockSize {
55 BitField<0, 4, u32> width;
56 BitField<4, 4, u32> height;
57 BitField<8, 4, u32> depth;
58 BitField<12, 4, u32> gob_height;
59 };
60 static_assert(sizeof(BlockSize) == 4);
61
62 union Origin {
63 BitField<0, 16, u32> x;
64 BitField<16, 16, u32> y;
65 };
66 static_assert(sizeof(Origin) == 4);
67
68 struct Parameters {
69 BlockSize block_size;
70 u32 width;
71 u32 height;
72 u32 depth;
73 u32 layer;
74 Origin origin;
75 };
76 static_assert(sizeof(Parameters) == 24);
77
78 struct Semaphore { 108 struct Semaphore {
79 PackedGPUVAddr address; 109 PackedGPUVAddr address;
80 u32 payload; 110 u32 payload;
@@ -227,8 +257,6 @@ private:
227 257
228 void CopyBlockLinearToBlockLinear(); 258 void CopyBlockLinearToBlockLinear();
229 259
230 void FastCopyBlockLinearToPitch();
231
232 void ReleaseSemaphore(); 260 void ReleaseSemaphore();
233 261
234 void ConsumeSinkImpl() override; 262 void ConsumeSinkImpl() override;
@@ -261,17 +289,17 @@ private:
261 u32 reserved05[0x3f]; 289 u32 reserved05[0x3f];
262 PackedGPUVAddr offset_in; 290 PackedGPUVAddr offset_in;
263 PackedGPUVAddr offset_out; 291 PackedGPUVAddr offset_out;
264 u32 pitch_in; 292 s32 pitch_in;
265 u32 pitch_out; 293 s32 pitch_out;
266 u32 line_length_in; 294 u32 line_length_in;
267 u32 line_count; 295 u32 line_count;
268 u32 reserved06[0xb6]; 296 u32 reserved06[0xb6];
269 u32 remap_consta_value; 297 u32 remap_consta_value;
270 u32 remap_constb_value; 298 u32 remap_constb_value;
271 RemapConst remap_const; 299 RemapConst remap_const;
272 Parameters dst_params; 300 DMA::Parameters dst_params;
273 u32 reserved07[0x1]; 301 u32 reserved07[0x1];
274 Parameters src_params; 302 DMA::Parameters src_params;
275 u32 reserved08[0x275]; 303 u32 reserved08[0x275];
276 u32 pm_trigger_end; 304 u32 pm_trigger_end;
277 u32 reserved09[0x3ba]; 305 u32 reserved09[0x3ba];
diff --git a/src/video_core/framebuffer_config.h b/src/video_core/framebuffer_config.h
index d93f5a37f..5f3bffcab 100644
--- a/src/video_core/framebuffer_config.h
+++ b/src/video_core/framebuffer_config.h
@@ -5,8 +5,8 @@
5 5
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "common/math_util.h" 7#include "common/math_util.h"
8#include "core/hle/service/nvflinger/buffer_transform_flags.h" 8#include "core/hle/service/nvnflinger/buffer_transform_flags.h"
9#include "core/hle/service/nvflinger/pixel_format.h" 9#include "core/hle/service/nvnflinger/pixel_format.h"
10 10
11namespace Tegra { 11namespace Tegra {
12 12
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 7024a19cf..2e7f9c5ed 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -197,7 +197,7 @@ struct GPU::Impl {
197 constexpr u64 gpu_ticks_num = 384; 197 constexpr u64 gpu_ticks_num = 384;
198 constexpr u64 gpu_ticks_den = 625; 198 constexpr u64 gpu_ticks_den = 625;
199 199
200 u64 nanoseconds = system.CoreTiming().GetGlobalTimeNs().count(); 200 u64 nanoseconds = system.CoreTiming().GetCPUTimeNs().count();
201 if (Settings::values.use_fast_gpu_time.GetValue()) { 201 if (Settings::values.use_fast_gpu_time.GetValue()) {
202 nanoseconds /= 256; 202 nanoseconds /= 256;
203 } 203 }
diff --git a/src/video_core/renderer_null/null_rasterizer.h b/src/video_core/renderer_null/null_rasterizer.h
index 51f896e43..0c59e6a1f 100644
--- a/src/video_core/renderer_null/null_rasterizer.h
+++ b/src/video_core/renderer_null/null_rasterizer.h
@@ -22,6 +22,14 @@ public:
22 explicit AccelerateDMA(); 22 explicit AccelerateDMA();
23 bool BufferCopy(GPUVAddr start_address, GPUVAddr end_address, u64 amount) override; 23 bool BufferCopy(GPUVAddr start_address, GPUVAddr end_address, u64 amount) override;
24 bool BufferClear(GPUVAddr src_address, u64 amount, u32 value) override; 24 bool BufferClear(GPUVAddr src_address, u64 amount, u32 value) override;
25 bool ImageToBuffer(const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::ImageOperand& src,
26 const Tegra::DMA::BufferOperand& dst) override {
27 return false;
28 }
29 bool BufferToImage(const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::BufferOperand& src,
30 const Tegra::DMA::ImageOperand& dst) override {
31 return false;
32 }
25}; 33};
26 34
27class RasterizerNull final : public VideoCore::RasterizerAccelerated, 35class RasterizerNull final : public VideoCore::RasterizerAccelerated,
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 0c45832ae..7e21fc43d 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -56,6 +56,16 @@ public:
56 56
57 bool BufferClear(GPUVAddr src_address, u64 amount, u32 value) override; 57 bool BufferClear(GPUVAddr src_address, u64 amount, u32 value) override;
58 58
59 bool ImageToBuffer(const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::ImageOperand& src,
60 const Tegra::DMA::BufferOperand& dst) override {
61 return false;
62 }
63
64 bool BufferToImage(const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::BufferOperand& src,
65 const Tegra::DMA::ImageOperand& dst) override {
66 return false;
67 }
68
59private: 69private:
60 BufferCache& buffer_cache; 70 BufferCache& buffer_cache;
61}; 71};
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index eb6e43a08..d3eabd686 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -112,13 +112,17 @@ GLenum ImageTarget(Shader::TextureType type, int num_samples = 1) {
112 return GL_NONE; 112 return GL_NONE;
113} 113}
114 114
115GLenum TextureMode(PixelFormat format, bool is_first) { 115GLenum TextureMode(PixelFormat format, std::array<SwizzleSource, 4> swizzle) {
116 bool any_r =
117 std::ranges::any_of(swizzle, [](SwizzleSource s) { return s == SwizzleSource::R; });
116 switch (format) { 118 switch (format) {
117 case PixelFormat::D24_UNORM_S8_UINT: 119 case PixelFormat::D24_UNORM_S8_UINT:
118 case PixelFormat::D32_FLOAT_S8_UINT: 120 case PixelFormat::D32_FLOAT_S8_UINT:
119 return is_first ? GL_DEPTH_COMPONENT : GL_STENCIL_INDEX; 121 // R = depth, G = stencil
122 return any_r ? GL_DEPTH_COMPONENT : GL_STENCIL_INDEX;
120 case PixelFormat::S8_UINT_D24_UNORM: 123 case PixelFormat::S8_UINT_D24_UNORM:
121 return is_first ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT; 124 // R = stencil, G = depth
125 return any_r ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT;
122 default: 126 default:
123 ASSERT(false); 127 ASSERT(false);
124 return GL_DEPTH_COMPONENT; 128 return GL_DEPTH_COMPONENT;
@@ -208,8 +212,7 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array<SwizzleSource, 4
208 case PixelFormat::D32_FLOAT_S8_UINT: 212 case PixelFormat::D32_FLOAT_S8_UINT:
209 case PixelFormat::S8_UINT_D24_UNORM: 213 case PixelFormat::S8_UINT_D24_UNORM:
210 UNIMPLEMENTED_IF(swizzle[0] != SwizzleSource::R && swizzle[0] != SwizzleSource::G); 214 UNIMPLEMENTED_IF(swizzle[0] != SwizzleSource::R && swizzle[0] != SwizzleSource::G);
211 glTextureParameteri(handle, GL_DEPTH_STENCIL_TEXTURE_MODE, 215 glTextureParameteri(handle, GL_DEPTH_STENCIL_TEXTURE_MODE, TextureMode(format, swizzle));
212 TextureMode(format, swizzle[0] == SwizzleSource::R));
213 std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed); 216 std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed);
214 break; 217 break;
215 case PixelFormat::A5B5G5R1_UNORM: { 218 case PixelFormat::A5B5G5R1_UNORM: {
@@ -228,8 +231,9 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array<SwizzleSource, 4
228 231
229[[nodiscard]] bool CanBeAccelerated(const TextureCacheRuntime& runtime, 232[[nodiscard]] bool CanBeAccelerated(const TextureCacheRuntime& runtime,
230 const VideoCommon::ImageInfo& info) { 233 const VideoCommon::ImageInfo& info) {
231 if (IsPixelFormatASTC(info.format)) { 234 if (IsPixelFormatASTC(info.format) && !runtime.HasNativeASTC()) {
232 return !runtime.HasNativeASTC() && Settings::values.accelerate_astc.GetValue(); 235 return Settings::values.accelerate_astc.GetValue() &&
236 !Settings::values.async_astc.GetValue();
233 } 237 }
234 // Disable other accelerated uploads for now as they don't implement swizzled uploads 238 // Disable other accelerated uploads for now as they don't implement swizzled uploads
235 return false; 239 return false;
@@ -258,6 +262,14 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array<SwizzleSource, 4
258 return format_info.compatibility_class == store_class; 262 return format_info.compatibility_class == store_class;
259} 263}
260 264
265[[nodiscard]] bool CanBeDecodedAsync(const TextureCacheRuntime& runtime,
266 const VideoCommon::ImageInfo& info) {
267 if (IsPixelFormatASTC(info.format) && !runtime.HasNativeASTC()) {
268 return Settings::values.async_astc.GetValue();
269 }
270 return false;
271}
272
261[[nodiscard]] CopyOrigin MakeCopyOrigin(VideoCommon::Offset3D offset, 273[[nodiscard]] CopyOrigin MakeCopyOrigin(VideoCommon::Offset3D offset,
262 VideoCommon::SubresourceLayers subresource, GLenum target) { 274 VideoCommon::SubresourceLayers subresource, GLenum target) {
263 switch (target) { 275 switch (target) {
@@ -721,7 +733,9 @@ std::optional<size_t> TextureCacheRuntime::StagingBuffers::FindBuffer(size_t req
721Image::Image(TextureCacheRuntime& runtime_, const VideoCommon::ImageInfo& info_, GPUVAddr gpu_addr_, 733Image::Image(TextureCacheRuntime& runtime_, const VideoCommon::ImageInfo& info_, GPUVAddr gpu_addr_,
722 VAddr cpu_addr_) 734 VAddr cpu_addr_)
723 : VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), runtime{&runtime_} { 735 : VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), runtime{&runtime_} {
724 if (CanBeAccelerated(*runtime, info)) { 736 if (CanBeDecodedAsync(*runtime, info)) {
737 flags |= ImageFlagBits::AsynchronousDecode;
738 } else if (CanBeAccelerated(*runtime, info)) {
725 flags |= ImageFlagBits::AcceleratedUpload; 739 flags |= ImageFlagBits::AcceleratedUpload;
726 } 740 }
727 if (IsConverted(runtime->device, info.format, info.type)) { 741 if (IsConverted(runtime->device, info.format, info.type)) {
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index b0153a502..9cbcb3c8f 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -238,7 +238,7 @@ private:
238 return indices; 238 return indices;
239 } 239 }
240 240
241 void MakeAndUpdateIndices(u8* staging_data, size_t quad_size, u32 quad, u32 first) { 241 void MakeAndUpdateIndices(u8* staging_data, size_t quad_size, u32 quad, u32 first) override {
242 switch (index_type) { 242 switch (index_type) {
243 case VK_INDEX_TYPE_UINT8_EXT: 243 case VK_INDEX_TYPE_UINT8_EXT:
244 std::memcpy(staging_data, MakeIndices<u8>(quad, first).data(), quad_size); 244 std::memcpy(staging_data, MakeIndices<u8>(quad, first).data(), quad_size);
@@ -278,7 +278,7 @@ private:
278 return indices; 278 return indices;
279 } 279 }
280 280
281 void MakeAndUpdateIndices(u8* staging_data, size_t quad_size, u32 quad, u32 first) { 281 void MakeAndUpdateIndices(u8* staging_data, size_t quad_size, u32 quad, u32 first) override {
282 switch (index_type) { 282 switch (index_type) {
283 case VK_INDEX_TYPE_UINT8_EXT: 283 case VK_INDEX_TYPE_UINT8_EXT:
284 std::memcpy(staging_data, MakeIndices<u8>(quad, first).data(), quad_size); 284 std::memcpy(staging_data, MakeIndices<u8>(quad, first).data(), quad_size);
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 719edbcfb..25965b684 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -172,7 +172,7 @@ RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra
172 buffer_cache(*this, cpu_memory_, buffer_cache_runtime), 172 buffer_cache(*this, cpu_memory_, buffer_cache_runtime),
173 pipeline_cache(*this, device, scheduler, descriptor_pool, update_descriptor_queue, 173 pipeline_cache(*this, device, scheduler, descriptor_pool, update_descriptor_queue,
174 render_pass_cache, buffer_cache, texture_cache, gpu.ShaderNotify()), 174 render_pass_cache, buffer_cache, texture_cache, gpu.ShaderNotify()),
175 query_cache{*this, device, scheduler}, accelerate_dma{buffer_cache}, 175 query_cache{*this, device, scheduler}, accelerate_dma(buffer_cache, texture_cache, scheduler),
176 fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache, device, scheduler), 176 fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache, device, scheduler),
177 wfi_event(device.GetLogical().CreateEvent()) { 177 wfi_event(device.GetLogical().CreateEvent()) {
178 scheduler.SetQueryCache(query_cache); 178 scheduler.SetQueryCache(query_cache);
@@ -756,7 +756,9 @@ void RasterizerVulkan::FlushWork() {
756 draw_counter = 0; 756 draw_counter = 0;
757} 757}
758 758
759AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_) : buffer_cache{buffer_cache_} {} 759AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_, TextureCache& texture_cache_,
760 Scheduler& scheduler_)
761 : buffer_cache{buffer_cache_}, texture_cache{texture_cache_}, scheduler{scheduler_} {}
760 762
761bool AccelerateDMA::BufferClear(GPUVAddr src_address, u64 amount, u32 value) { 763bool AccelerateDMA::BufferClear(GPUVAddr src_address, u64 amount, u32 value) {
762 std::scoped_lock lock{buffer_cache.mutex}; 764 std::scoped_lock lock{buffer_cache.mutex};
@@ -768,6 +770,234 @@ bool AccelerateDMA::BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64
768 return buffer_cache.DMACopy(src_address, dest_address, amount); 770 return buffer_cache.DMACopy(src_address, dest_address, amount);
769} 771}
770 772
773bool AccelerateDMA::ImageToBuffer(const Tegra::DMA::ImageCopy& copy_info,
774 const Tegra::DMA::ImageOperand& src,
775 const Tegra::DMA::BufferOperand& dst) {
776 std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
777 auto query_image = texture_cache.ObtainImage(src, false);
778 if (!query_image) {
779 return false;
780 }
781 auto* image = query_image->first;
782 auto [level, base] = query_image->second;
783 const u32 buffer_size = static_cast<u32>(dst.pitch * dst.height);
784 const auto [buffer, offset] = buffer_cache.ObtainBuffer(
785 dst.address, buffer_size, VideoCommon::ObtainBufferSynchronize::FullSynchronize,
786 VideoCommon::ObtainBufferOperation::MarkAsWritten);
787
788 const bool is_rescaled = image->IsRescaled();
789 if (is_rescaled) {
790 image->ScaleDown();
791 }
792 VkImageSubresourceLayers subresources{
793 .aspectMask = image->AspectMask(),
794 .mipLevel = level,
795 .baseArrayLayer = base,
796 .layerCount = 1,
797 };
798 const u32 bpp = VideoCore::Surface::BytesPerBlock(image->info.format);
799 const auto convert = [old_bpp = src.bytes_per_pixel, bpp](u32 value) {
800 return (old_bpp * value) / bpp;
801 };
802 const u32 base_x = convert(src.params.origin.x.Value());
803 const u32 base_y = src.params.origin.y.Value();
804 const u32 length_x = convert(copy_info.length_x);
805 const u32 length_y = copy_info.length_y;
806 VkOffset3D image_offset{
807 .x = static_cast<s32>(base_x),
808 .y = static_cast<s32>(base_y),
809 .z = 0,
810 };
811 VkExtent3D image_extent{
812 .width = length_x,
813 .height = length_y,
814 .depth = 1,
815 };
816 auto buff_info(dst);
817 buff_info.pitch = convert(dst.pitch);
818 scheduler.RequestOutsideRenderPassOperationContext();
819 scheduler.Record([src_image = image->Handle(), dst_buffer = buffer->Handle(),
820 buffer_offset = offset, subresources, image_offset, image_extent,
821 buff_info](vk::CommandBuffer cmdbuf) {
822 const std::array buffer_copy_info{
823 VkBufferImageCopy{
824 .bufferOffset = buffer_offset,
825 .bufferRowLength = buff_info.pitch,
826 .bufferImageHeight = buff_info.height,
827 .imageSubresource = subresources,
828 .imageOffset = image_offset,
829 .imageExtent = image_extent,
830 },
831 };
832 const VkImageSubresourceRange range{
833 .aspectMask = subresources.aspectMask,
834 .baseMipLevel = subresources.mipLevel,
835 .levelCount = 1,
836 .baseArrayLayer = subresources.baseArrayLayer,
837 .layerCount = 1,
838 };
839 static constexpr VkMemoryBarrier WRITE_BARRIER{
840 .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
841 .pNext = nullptr,
842 .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
843 .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
844 };
845 const std::array pre_barriers{
846 VkImageMemoryBarrier{
847 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
848 .pNext = nullptr,
849 .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
850 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
851 VK_ACCESS_TRANSFER_WRITE_BIT,
852 .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
853 .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
854 .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
855 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
856 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
857 .image = src_image,
858 .subresourceRange = range,
859 },
860 };
861 const std::array post_barriers{
862 VkImageMemoryBarrier{
863 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
864 .pNext = nullptr,
865 .srcAccessMask = 0,
866 .dstAccessMask = 0,
867 .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
868 .newLayout = VK_IMAGE_LAYOUT_GENERAL,
869 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
870 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
871 .image = src_image,
872 .subresourceRange = range,
873 },
874 };
875 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
876 0, {}, {}, pre_barriers);
877 cmdbuf.CopyImageToBuffer(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_buffer,
878 buffer_copy_info);
879 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
880 0, WRITE_BARRIER, nullptr, post_barriers);
881 });
882 if (is_rescaled) {
883 image->ScaleUp(true);
884 }
885 return true;
886}
887
888bool AccelerateDMA::BufferToImage(const Tegra::DMA::ImageCopy& copy_info,
889 const Tegra::DMA::BufferOperand& src,
890 const Tegra::DMA::ImageOperand& dst) {
891 std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
892 auto query_image = texture_cache.ObtainImage(dst, true);
893 if (!query_image) {
894 return false;
895 }
896 auto* image = query_image->first;
897 auto [level, base] = query_image->second;
898 const u32 buffer_size = static_cast<u32>(src.pitch * src.height);
899 const auto [buffer, offset] = buffer_cache.ObtainBuffer(
900 src.address, buffer_size, VideoCommon::ObtainBufferSynchronize::FullSynchronize,
901 VideoCommon::ObtainBufferOperation::DoNothing);
902 const bool is_rescaled = image->IsRescaled();
903 if (is_rescaled) {
904 image->ScaleDown(true);
905 }
906 VkImageSubresourceLayers subresources{
907 .aspectMask = image->AspectMask(),
908 .mipLevel = level,
909 .baseArrayLayer = base,
910 .layerCount = 1,
911 };
912 const u32 bpp = VideoCore::Surface::BytesPerBlock(image->info.format);
913 const auto convert = [old_bpp = dst.bytes_per_pixel, bpp](u32 value) {
914 return (old_bpp * value) / bpp;
915 };
916 const u32 base_x = convert(dst.params.origin.x.Value());
917 const u32 base_y = dst.params.origin.y.Value();
918 const u32 length_x = convert(copy_info.length_x);
919 const u32 length_y = copy_info.length_y;
920 VkOffset3D image_offset{
921 .x = static_cast<s32>(base_x),
922 .y = static_cast<s32>(base_y),
923 .z = 0,
924 };
925 VkExtent3D image_extent{
926 .width = length_x,
927 .height = length_y,
928 .depth = 1,
929 };
930 auto buff_info(src);
931 buff_info.pitch = convert(src.pitch);
932 scheduler.RequestOutsideRenderPassOperationContext();
933 scheduler.Record([dst_image = image->Handle(), src_buffer = buffer->Handle(),
934 buffer_offset = offset, subresources, image_offset, image_extent,
935 buff_info](vk::CommandBuffer cmdbuf) {
936 const std::array buffer_copy_info{
937 VkBufferImageCopy{
938 .bufferOffset = buffer_offset,
939 .bufferRowLength = buff_info.pitch,
940 .bufferImageHeight = buff_info.height,
941 .imageSubresource = subresources,
942 .imageOffset = image_offset,
943 .imageExtent = image_extent,
944 },
945 };
946 const VkImageSubresourceRange range{
947 .aspectMask = subresources.aspectMask,
948 .baseMipLevel = subresources.mipLevel,
949 .levelCount = 1,
950 .baseArrayLayer = subresources.baseArrayLayer,
951 .layerCount = 1,
952 };
953 static constexpr VkMemoryBarrier READ_BARRIER{
954 .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
955 .pNext = nullptr,
956 .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
957 .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
958 };
959 const std::array pre_barriers{
960 VkImageMemoryBarrier{
961 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
962 .pNext = nullptr,
963 .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
964 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
965 VK_ACCESS_TRANSFER_WRITE_BIT,
966 .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
967 .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
968 .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
969 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
970 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
971 .image = dst_image,
972 .subresourceRange = range,
973 },
974 };
975 const std::array post_barriers{
976 VkImageMemoryBarrier{
977 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
978 .pNext = nullptr,
979 .srcAccessMask = 0,
980 .dstAccessMask = 0,
981 .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
982 .newLayout = VK_IMAGE_LAYOUT_GENERAL,
983 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
984 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
985 .image = dst_image,
986 .subresourceRange = range,
987 },
988 };
989 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
990 0, READ_BARRIER, {}, pre_barriers);
991 cmdbuf.CopyBufferToImage(src_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, buffer_copy_info);
992 cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
993 0, nullptr, nullptr, post_barriers);
994 });
995 if (is_rescaled) {
996 image->ScaleUp();
997 }
998 return true;
999}
1000
771void RasterizerVulkan::UpdateDynamicStates() { 1001void RasterizerVulkan::UpdateDynamicStates() {
772 auto& regs = maxwell3d->regs; 1002 auto& regs = maxwell3d->regs;
773 UpdateViewportsState(regs); 1003 UpdateViewportsState(regs);
@@ -1064,7 +1294,7 @@ void RasterizerVulkan::UpdateDepthBoundsTestEnable(Tegra::Engines::Maxwell3D::Re
1064 LOG_WARNING(Render_Vulkan, "Depth bounds is enabled but not supported"); 1294 LOG_WARNING(Render_Vulkan, "Depth bounds is enabled but not supported");
1065 enabled = false; 1295 enabled = false;
1066 } 1296 }
1067 scheduler.Record([enable = regs.depth_bounds_enable](vk::CommandBuffer cmdbuf) { 1297 scheduler.Record([enable = enabled](vk::CommandBuffer cmdbuf) {
1068 cmdbuf.SetDepthBoundsTestEnableEXT(enable); 1298 cmdbuf.SetDepthBoundsTestEnableEXT(enable);
1069 }); 1299 });
1070} 1300}
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index a0508b57c..7746c5434 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -45,14 +45,23 @@ class StateTracker;
45 45
46class AccelerateDMA : public Tegra::Engines::AccelerateDMAInterface { 46class AccelerateDMA : public Tegra::Engines::AccelerateDMAInterface {
47public: 47public:
48 explicit AccelerateDMA(BufferCache& buffer_cache); 48 explicit AccelerateDMA(BufferCache& buffer_cache, TextureCache& texture_cache,
49 Scheduler& scheduler);
49 50
50 bool BufferCopy(GPUVAddr start_address, GPUVAddr end_address, u64 amount) override; 51 bool BufferCopy(GPUVAddr start_address, GPUVAddr end_address, u64 amount) override;
51 52
52 bool BufferClear(GPUVAddr src_address, u64 amount, u32 value) override; 53 bool BufferClear(GPUVAddr src_address, u64 amount, u32 value) override;
53 54
55 bool ImageToBuffer(const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::ImageOperand& src,
56 const Tegra::DMA::BufferOperand& dst) override;
57
58 bool BufferToImage(const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::BufferOperand& src,
59 const Tegra::DMA::ImageOperand& dst) override;
60
54private: 61private:
55 BufferCache& buffer_cache; 62 BufferCache& buffer_cache;
63 TextureCache& texture_cache;
64 Scheduler& scheduler;
56}; 65};
57 66
58class RasterizerVulkan final : public VideoCore::RasterizerAccelerated, 67class RasterizerVulkan final : public VideoCore::RasterizerAccelerated,
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 9b85dfb5e..e013d1c60 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -189,13 +189,16 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
189 if (info.IsRenderTarget()) { 189 if (info.IsRenderTarget()) {
190 return ImageAspectMask(info.format); 190 return ImageAspectMask(info.format);
191 } 191 }
192 const bool is_first = info.Swizzle()[0] == SwizzleSource::R; 192 bool any_r =
193 std::ranges::any_of(info.Swizzle(), [](SwizzleSource s) { return s == SwizzleSource::R; });
193 switch (info.format) { 194 switch (info.format) {
194 case PixelFormat::D24_UNORM_S8_UINT: 195 case PixelFormat::D24_UNORM_S8_UINT:
195 case PixelFormat::D32_FLOAT_S8_UINT: 196 case PixelFormat::D32_FLOAT_S8_UINT:
196 return is_first ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT; 197 // R = depth, G = stencil
198 return any_r ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT;
197 case PixelFormat::S8_UINT_D24_UNORM: 199 case PixelFormat::S8_UINT_D24_UNORM:
198 return is_first ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; 200 // R = stencil, G = depth
201 return any_r ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
199 case PixelFormat::D16_UNORM: 202 case PixelFormat::D16_UNORM:
200 case PixelFormat::D32_FLOAT: 203 case PixelFormat::D32_FLOAT:
201 return VK_IMAGE_ASPECT_DEPTH_BIT; 204 return VK_IMAGE_ASPECT_DEPTH_BIT;
@@ -864,13 +867,19 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
864 const VkImageAspectFlags src_aspect_mask = src.AspectMask(); 867 const VkImageAspectFlags src_aspect_mask = src.AspectMask();
865 const VkImageAspectFlags dst_aspect_mask = dst.AspectMask(); 868 const VkImageAspectFlags dst_aspect_mask = dst.AspectMask();
866 869
867 std::ranges::transform(copies, vk_in_copies.begin(), [src_aspect_mask](const auto& copy) { 870 const auto bpp_in = BytesPerBlock(src.info.format) / DefaultBlockWidth(src.info.format);
868 return MakeBufferImageCopy(copy, true, src_aspect_mask); 871 const auto bpp_out = BytesPerBlock(dst.info.format) / DefaultBlockWidth(dst.info.format);
869 }); 872 std::ranges::transform(copies, vk_in_copies.begin(),
873 [src_aspect_mask, bpp_in, bpp_out](const auto& copy) {
874 auto copy2 = copy;
875 copy2.src_offset.x = (bpp_out * copy.src_offset.x) / bpp_in;
876 copy2.extent.width = (bpp_out * copy.extent.width) / bpp_in;
877 return MakeBufferImageCopy(copy2, true, src_aspect_mask);
878 });
870 std::ranges::transform(copies, vk_out_copies.begin(), [dst_aspect_mask](const auto& copy) { 879 std::ranges::transform(copies, vk_out_copies.begin(), [dst_aspect_mask](const auto& copy) {
871 return MakeBufferImageCopy(copy, false, dst_aspect_mask); 880 return MakeBufferImageCopy(copy, false, dst_aspect_mask);
872 }); 881 });
873 const u32 img_bpp = BytesPerBlock(src.info.format); 882 const u32 img_bpp = BytesPerBlock(dst.info.format);
874 size_t total_size = 0; 883 size_t total_size = 0;
875 for (const auto& copy : copies) { 884 for (const auto& copy : copies) {
876 total_size += copy.extent.width * copy.extent.height * copy.extent.depth * img_bpp; 885 total_size += copy.extent.width * copy.extent.height * copy.extent.depth * img_bpp;
@@ -1256,11 +1265,12 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu
1256 commit(runtime_.memory_allocator.Commit(original_image, MemoryUsage::DeviceLocal)), 1265 commit(runtime_.memory_allocator.Commit(original_image, MemoryUsage::DeviceLocal)),
1257 aspect_mask(ImageAspectMask(info.format)) { 1266 aspect_mask(ImageAspectMask(info.format)) {
1258 if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) { 1267 if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) {
1259 if (Settings::values.accelerate_astc.GetValue()) { 1268 if (Settings::values.async_astc.GetValue()) {
1269 flags |= VideoCommon::ImageFlagBits::AsynchronousDecode;
1270 } else if (Settings::values.accelerate_astc.GetValue()) {
1260 flags |= VideoCommon::ImageFlagBits::AcceleratedUpload; 1271 flags |= VideoCommon::ImageFlagBits::AcceleratedUpload;
1261 } else {
1262 flags |= VideoCommon::ImageFlagBits::Converted;
1263 } 1272 }
1273 flags |= VideoCommon::ImageFlagBits::Converted;
1264 flags |= VideoCommon::ImageFlagBits::CostlyLoad; 1274 flags |= VideoCommon::ImageFlagBits::CostlyLoad;
1265 } 1275 }
1266 if (runtime->device.HasDebuggingToolAttached()) { 1276 if (runtime->device.HasDebuggingToolAttached()) {
@@ -1762,7 +1772,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
1762 .minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(), 1772 .minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(),
1763 .maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(), 1773 .maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(),
1764 .borderColor = 1774 .borderColor =
1765 arbitrary_borders ? VK_BORDER_COLOR_INT_CUSTOM_EXT : ConvertBorderColor(color), 1775 arbitrary_borders ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT : ConvertBorderColor(color),
1766 .unnormalizedCoordinates = VK_FALSE, 1776 .unnormalizedCoordinates = VK_FALSE,
1767 }); 1777 });
1768} 1778}
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h
index 620565684..e8fa592d2 100644
--- a/src/video_core/texture_cache/image_base.h
+++ b/src/video_core/texture_cache/image_base.h
@@ -38,6 +38,9 @@ enum class ImageFlagBits : u32 {
38 Rescaled = 1 << 13, 38 Rescaled = 1 << 13,
39 CheckingRescalable = 1 << 14, 39 CheckingRescalable = 1 << 14,
40 IsRescalable = 1 << 15, 40 IsRescalable = 1 << 15,
41
42 AsynchronousDecode = 1 << 16,
43 IsDecoding = 1 << 17, ///< Is currently being decoded asynchornously.
41}; 44};
42DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits) 45DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)
43 46
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index e9100091e..a1296b574 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -216,10 +216,51 @@ ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept {
216 .height = config.height, 216 .height = config.height,
217 .depth = 1, 217 .depth = 1,
218 }; 218 };
219 rescaleable = block.depth == 0; 219 rescaleable = block.depth == 0 && size.height > 256;
220 rescaleable &= size.height > 256;
221 downscaleable = size.height > 512; 220 downscaleable = size.height > 512;
222 } 221 }
223} 222}
224 223
224static PixelFormat ByteSizeToFormat(u32 bytes_per_pixel) {
225 switch (bytes_per_pixel) {
226 case 1:
227 return PixelFormat::R8_UINT;
228 case 2:
229 return PixelFormat::R8G8_UINT;
230 case 4:
231 return PixelFormat::A8B8G8R8_UINT;
232 case 8:
233 return PixelFormat::R16G16B16A16_UINT;
234 case 16:
235 return PixelFormat::R32G32B32A32_UINT;
236 default:
237 UNIMPLEMENTED();
238 return PixelFormat::Invalid;
239 }
240}
241
242ImageInfo::ImageInfo(const Tegra::DMA::ImageOperand& config) noexcept {
243 const u32 bytes_per_pixel = config.bytes_per_pixel;
244 format = ByteSizeToFormat(bytes_per_pixel);
245 type = config.params.block_size.depth > 0 ? ImageType::e3D : ImageType::e2D;
246 num_samples = 1;
247 block = Extent3D{
248 .width = config.params.block_size.width,
249 .height = config.params.block_size.height,
250 .depth = config.params.block_size.depth,
251 };
252 size = Extent3D{
253 .width = config.params.width,
254 .height = config.params.height,
255 .depth = config.params.depth,
256 };
257 tile_width_spacing = 0;
258 resources.levels = 1;
259 resources.layers = 1;
260 layer_stride = CalculateLayerStride(*this);
261 maybe_unaligned_layer_stride = CalculateLayerSize(*this);
262 rescaleable = block.depth == 0 && size.height > 256;
263 downscaleable = size.height > 512;
264}
265
225} // namespace VideoCommon 266} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h
index 93755e15e..a12f5b44f 100644
--- a/src/video_core/texture_cache/image_info.h
+++ b/src/video_core/texture_cache/image_info.h
@@ -5,6 +5,7 @@
5 5
6#include "video_core/engines/fermi_2d.h" 6#include "video_core/engines/fermi_2d.h"
7#include "video_core/engines/maxwell_3d.h" 7#include "video_core/engines/maxwell_3d.h"
8#include "video_core/engines/maxwell_dma.h"
8#include "video_core/surface.h" 9#include "video_core/surface.h"
9#include "video_core/texture_cache/types.h" 10#include "video_core/texture_cache/types.h"
10 11
@@ -19,6 +20,7 @@ struct ImageInfo {
19 explicit ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) noexcept; 20 explicit ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) noexcept;
20 explicit ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept; 21 explicit ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept;
21 explicit ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept; 22 explicit ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept;
23 explicit ImageInfo(const Tegra::DMA::ImageOperand& config) noexcept;
22 24
23 PixelFormat format = PixelFormat::Invalid; 25 PixelFormat format = PixelFormat::Invalid;
24 ImageType type = ImageType::e1D; 26 ImageType type = ImageType::e1D;
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 3e2cbb0b0..335338434 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -85,6 +85,11 @@ void TextureCache<P>::RunGarbageCollector() {
85 } 85 }
86 --num_iterations; 86 --num_iterations;
87 auto& image = slot_images[image_id]; 87 auto& image = slot_images[image_id];
88 if (True(image.flags & ImageFlagBits::IsDecoding)) {
89 // This image is still being decoded, deleting it will invalidate the slot
90 // used by the async decoder thread.
91 return false;
92 }
88 const bool must_download = 93 const bool must_download =
89 image.IsSafeDownload() && False(image.flags & ImageFlagBits::BadOverlap); 94 image.IsSafeDownload() && False(image.flags & ImageFlagBits::BadOverlap);
90 if (!high_priority_mode && 95 if (!high_priority_mode &&
@@ -133,6 +138,8 @@ void TextureCache<P>::TickFrame() {
133 sentenced_images.Tick(); 138 sentenced_images.Tick();
134 sentenced_framebuffers.Tick(); 139 sentenced_framebuffers.Tick();
135 sentenced_image_view.Tick(); 140 sentenced_image_view.Tick();
141 TickAsyncDecode();
142
136 runtime.TickFrame(); 143 runtime.TickFrame();
137 critical_gc = 0; 144 critical_gc = 0;
138 ++frame_tick; 145 ++frame_tick;
@@ -777,6 +784,10 @@ void TextureCache<P>::RefreshContents(Image& image, ImageId image_id) {
777 LOG_WARNING(HW_GPU, "MSAA image uploads are not implemented"); 784 LOG_WARNING(HW_GPU, "MSAA image uploads are not implemented");
778 return; 785 return;
779 } 786 }
787 if (True(image.flags & ImageFlagBits::AsynchronousDecode)) {
788 QueueAsyncDecode(image, image_id);
789 return;
790 }
780 auto staging = runtime.UploadStagingBuffer(MapSizeBytes(image)); 791 auto staging = runtime.UploadStagingBuffer(MapSizeBytes(image));
781 UploadImageContents(image, staging); 792 UploadImageContents(image, staging);
782 runtime.InsertUploadMemoryBarrier(); 793 runtime.InsertUploadMemoryBarrier();
@@ -990,6 +1001,65 @@ u64 TextureCache<P>::GetScaledImageSizeBytes(const ImageBase& image) {
990} 1001}
991 1002
992template <class P> 1003template <class P>
1004void TextureCache<P>::QueueAsyncDecode(Image& image, ImageId image_id) {
1005 UNIMPLEMENTED_IF(False(image.flags & ImageFlagBits::Converted));
1006 LOG_INFO(HW_GPU, "Queuing async texture decode");
1007
1008 image.flags |= ImageFlagBits::IsDecoding;
1009 auto decode = std::make_unique<AsyncDecodeContext>();
1010 auto* decode_ptr = decode.get();
1011 decode->image_id = image_id;
1012 async_decodes.push_back(std::move(decode));
1013
1014 Common::ScratchBuffer<u8> local_unswizzle_data_buffer(image.unswizzled_size_bytes);
1015 const size_t guest_size_bytes = image.guest_size_bytes;
1016 swizzle_data_buffer.resize_destructive(guest_size_bytes);
1017 gpu_memory->ReadBlockUnsafe(image.gpu_addr, swizzle_data_buffer.data(), guest_size_bytes);
1018 auto copies = UnswizzleImage(*gpu_memory, image.gpu_addr, image.info, swizzle_data_buffer,
1019 local_unswizzle_data_buffer);
1020 const size_t out_size = MapSizeBytes(image);
1021
1022 auto func = [out_size, copies, info = image.info,
1023 input = std::move(local_unswizzle_data_buffer),
1024 async_decode = decode_ptr]() mutable {
1025 async_decode->decoded_data.resize_destructive(out_size);
1026 std::span copies_span{copies.data(), copies.size()};
1027 ConvertImage(input, info, async_decode->decoded_data, copies_span);
1028
1029 // TODO: Do we need this lock?
1030 std::unique_lock lock{async_decode->mutex};
1031 async_decode->copies = std::move(copies);
1032 async_decode->complete = true;
1033 };
1034 texture_decode_worker.QueueWork(std::move(func));
1035}
1036
1037template <class P>
1038void TextureCache<P>::TickAsyncDecode() {
1039 bool has_uploads{};
1040 auto i = async_decodes.begin();
1041 while (i != async_decodes.end()) {
1042 auto* async_decode = i->get();
1043 std::unique_lock lock{async_decode->mutex};
1044 if (!async_decode->complete) {
1045 ++i;
1046 continue;
1047 }
1048 Image& image = slot_images[async_decode->image_id];
1049 auto staging = runtime.UploadStagingBuffer(MapSizeBytes(image));
1050 std::memcpy(staging.mapped_span.data(), async_decode->decoded_data.data(),
1051 async_decode->decoded_data.size());
1052 image.UploadMemory(staging, async_decode->copies);
1053 image.flags &= ~ImageFlagBits::IsDecoding;
1054 has_uploads = true;
1055 i = async_decodes.erase(i);
1056 }
1057 if (has_uploads) {
1058 runtime.InsertUploadMemoryBarrier();
1059 }
1060}
1061
1062template <class P>
993bool TextureCache<P>::ScaleUp(Image& image) { 1063bool TextureCache<P>::ScaleUp(Image& image) {
994 const bool has_copy = image.HasScaled(); 1064 const bool has_copy = image.HasScaled();
995 const bool rescaled = image.ScaleUp(); 1065 const bool rescaled = image.ScaleUp();
@@ -1289,6 +1359,75 @@ std::optional<typename TextureCache<P>::BlitImages> TextureCache<P>::GetBlitImag
1289} 1359}
1290 1360
1291template <class P> 1361template <class P>
1362ImageId TextureCache<P>::FindDMAImage(const ImageInfo& info, GPUVAddr gpu_addr) {
1363 std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
1364 if (!cpu_addr) {
1365 cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr, CalculateGuestSizeInBytes(info));
1366 if (!cpu_addr) {
1367 return ImageId{};
1368 }
1369 }
1370 ImageId image_id{};
1371 boost::container::small_vector<ImageId, 1> image_ids;
1372 const auto lambda = [&](ImageId existing_image_id, ImageBase& existing_image) {
1373 if (True(existing_image.flags & ImageFlagBits::Remapped)) {
1374 return false;
1375 }
1376 if (info.type == ImageType::Linear || existing_image.info.type == ImageType::Linear)
1377 [[unlikely]] {
1378 const bool strict_size = True(existing_image.flags & ImageFlagBits::Strong);
1379 const ImageInfo& existing = existing_image.info;
1380 if (existing_image.gpu_addr == gpu_addr && existing.type == info.type &&
1381 existing.pitch == info.pitch &&
1382 IsPitchLinearSameSize(existing, info, strict_size) &&
1383 IsViewCompatible(existing.format, info.format, false, true)) {
1384 image_id = existing_image_id;
1385 image_ids.push_back(existing_image_id);
1386 return true;
1387 }
1388 } else if (IsSubCopy(info, existing_image, gpu_addr)) {
1389 image_id = existing_image_id;
1390 image_ids.push_back(existing_image_id);
1391 return true;
1392 }
1393 return false;
1394 };
1395 ForEachImageInRegion(*cpu_addr, CalculateGuestSizeInBytes(info), lambda);
1396 if (image_ids.size() <= 1) [[likely]] {
1397 return image_id;
1398 }
1399 auto image_ids_compare = [this](ImageId a, ImageId b) {
1400 auto& image_a = slot_images[a];
1401 auto& image_b = slot_images[b];
1402 return image_a.modification_tick < image_b.modification_tick;
1403 };
1404 return *std::ranges::max_element(image_ids, image_ids_compare);
1405}
1406
1407template <class P>
1408std::optional<std::pair<typename TextureCache<P>::Image*, std::pair<u32, u32>>>
1409TextureCache<P>::ObtainImage(const Tegra::DMA::ImageOperand& operand, bool mark_as_modified) {
1410 ImageInfo dst_info(operand);
1411 ImageId dst_id = FindDMAImage(dst_info, operand.address);
1412 if (!dst_id) {
1413 return std::nullopt;
1414 }
1415 auto& image = slot_images[dst_id];
1416 auto base = image.TryFindBase(operand.address);
1417 if (!base) {
1418 return std::nullopt;
1419 }
1420 if (False(image.flags & ImageFlagBits::GpuModified)) {
1421 // No need to waste time on an image that's synced with guest
1422 return std::nullopt;
1423 }
1424 PrepareImage(dst_id, mark_as_modified, false);
1425 auto& new_image = slot_images[dst_id];
1426 lru_cache.Touch(new_image.lru_index, frame_tick);
1427 return std::make_pair(&new_image, std::make_pair(base->level, base->layer));
1428}
1429
1430template <class P>
1292SamplerId TextureCache<P>::FindSampler(const TSCEntry& config) { 1431SamplerId TextureCache<P>::FindSampler(const TSCEntry& config) {
1293 if (std::ranges::all_of(config.raw, [](u64 value) { return value == 0; })) { 1432 if (std::ranges::all_of(config.raw, [](u64 value) { return value == 0; })) {
1294 return NULL_SAMPLER_ID; 1433 return NULL_SAMPLER_ID;
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 485eaabaa..848a5d9ea 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <atomic>
6#include <deque> 7#include <deque>
7#include <limits> 8#include <limits>
8#include <mutex> 9#include <mutex>
@@ -18,6 +19,7 @@
18#include "common/lru_cache.h" 19#include "common/lru_cache.h"
19#include "common/polyfill_ranges.h" 20#include "common/polyfill_ranges.h"
20#include "common/scratch_buffer.h" 21#include "common/scratch_buffer.h"
22#include "common/thread_worker.h"
21#include "video_core/compatible_formats.h" 23#include "video_core/compatible_formats.h"
22#include "video_core/control/channel_state_cache.h" 24#include "video_core/control/channel_state_cache.h"
23#include "video_core/delayed_destruction_ring.h" 25#include "video_core/delayed_destruction_ring.h"
@@ -54,6 +56,14 @@ struct ImageViewInOut {
54 ImageViewId id{}; 56 ImageViewId id{};
55}; 57};
56 58
59struct AsyncDecodeContext {
60 ImageId image_id;
61 Common::ScratchBuffer<u8> decoded_data;
62 std::vector<BufferImageCopy> copies;
63 std::mutex mutex;
64 std::atomic_bool complete;
65};
66
57using TextureCacheGPUMap = std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>>; 67using TextureCacheGPUMap = std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>>;
58 68
59class TextureCacheChannelInfo : public ChannelInfo { 69class TextureCacheChannelInfo : public ChannelInfo {
@@ -199,6 +209,9 @@ public:
199 /// Pop asynchronous downloads 209 /// Pop asynchronous downloads
200 void PopAsyncFlushes(); 210 void PopAsyncFlushes();
201 211
212 [[nodiscard]] std::optional<std::pair<Image*, std::pair<u32, u32>>> ObtainImage(
213 const Tegra::DMA::ImageOperand& operand, bool mark_as_modified);
214
202 /// Return true when a CPU region is modified from the GPU 215 /// Return true when a CPU region is modified from the GPU
203 [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); 216 [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size);
204 217
@@ -290,6 +303,8 @@ private:
290 /// Remove joined images from the cache 303 /// Remove joined images from the cache
291 [[nodiscard]] ImageId JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VAddr cpu_addr); 304 [[nodiscard]] ImageId JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VAddr cpu_addr);
292 305
306 [[nodiscard]] ImageId FindDMAImage(const ImageInfo& info, GPUVAddr gpu_addr);
307
293 /// Return a blit image pair from the given guest blit parameters 308 /// Return a blit image pair from the given guest blit parameters
294 [[nodiscard]] std::optional<BlitImages> GetBlitImages( 309 [[nodiscard]] std::optional<BlitImages> GetBlitImages(
295 const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Surface& src, 310 const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Surface& src,
@@ -377,6 +392,9 @@ private:
377 bool ScaleDown(Image& image); 392 bool ScaleDown(Image& image);
378 u64 GetScaledImageSizeBytes(const ImageBase& image); 393 u64 GetScaledImageSizeBytes(const ImageBase& image);
379 394
395 void QueueAsyncDecode(Image& image, ImageId image_id);
396 void TickAsyncDecode();
397
380 Runtime& runtime; 398 Runtime& runtime;
381 399
382 VideoCore::RasterizerInterface& rasterizer; 400 VideoCore::RasterizerInterface& rasterizer;
@@ -430,6 +448,9 @@ private:
430 448
431 u64 modification_tick = 0; 449 u64 modification_tick = 0;
432 u64 frame_tick = 0; 450 u64 frame_tick = 0;
451
452 Common::ThreadWorker texture_decode_worker{1, "TextureDecoder"};
453 std::vector<std::unique_ptr<AsyncDecodeContext>> async_decodes;
433}; 454};
434 455
435} // namespace VideoCommon 456} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/types.h b/src/video_core/texture_cache/types.h
index 0453456b4..a0e10643f 100644
--- a/src/video_core/texture_cache/types.h
+++ b/src/video_core/texture_cache/types.h
@@ -54,6 +54,7 @@ enum class RelaxedOptions : u32 {
54 Format = 1 << 1, 54 Format = 1 << 1,
55 Samples = 1 << 2, 55 Samples = 1 << 2,
56 ForceBrokenViews = 1 << 3, 56 ForceBrokenViews = 1 << 3,
57 FormatBpp = 1 << 4,
57}; 58};
58DECLARE_ENUM_FLAG_OPERATORS(RelaxedOptions) 59DECLARE_ENUM_FLAG_OPERATORS(RelaxedOptions)
59 60
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp
index 697f86641..de37db684 100644
--- a/src/video_core/texture_cache/util.cpp
+++ b/src/video_core/texture_cache/util.cpp
@@ -743,6 +743,44 @@ std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, const ImageIn
743 return copies; 743 return copies;
744} 744}
745 745
746std::vector<ImageCopy> MakeReinterpretImageCopies(const ImageInfo& src, u32 up_scale,
747 u32 down_shift) {
748 std::vector<ImageCopy> copies;
749 copies.reserve(src.resources.levels);
750 const bool is_3d = src.type == ImageType::e3D;
751 for (s32 level = 0; level < src.resources.levels; ++level) {
752 ImageCopy& copy = copies.emplace_back();
753 copy.src_subresource = SubresourceLayers{
754 .base_level = level,
755 .base_layer = 0,
756 .num_layers = src.resources.layers,
757 };
758 copy.dst_subresource = SubresourceLayers{
759 .base_level = level,
760 .base_layer = 0,
761 .num_layers = src.resources.layers,
762 };
763 copy.src_offset = Offset3D{
764 .x = 0,
765 .y = 0,
766 .z = 0,
767 };
768 copy.dst_offset = Offset3D{
769 .x = 0,
770 .y = 0,
771 .z = 0,
772 };
773 const Extent3D mip_size = AdjustMipSize(src.size, level);
774 copy.extent = AdjustSamplesSize(mip_size, src.num_samples);
775 if (is_3d) {
776 copy.extent.depth = src.size.depth;
777 }
778 copy.extent.width = std::max<u32>((copy.extent.width * up_scale) >> down_shift, 1);
779 copy.extent.height = std::max<u32>((copy.extent.height * up_scale) >> down_shift, 1);
780 }
781 return copies;
782}
783
746bool IsValidEntry(const Tegra::MemoryManager& gpu_memory, const TICEntry& config) { 784bool IsValidEntry(const Tegra::MemoryManager& gpu_memory, const TICEntry& config) {
747 const GPUVAddr address = config.Address(); 785 const GPUVAddr address = config.Address();
748 if (address == 0) { 786 if (address == 0) {
@@ -999,6 +1037,20 @@ bool IsBlockLinearSizeCompatible(const ImageInfo& lhs, const ImageInfo& rhs, u32
999 } 1037 }
1000} 1038}
1001 1039
1040bool IsBlockLinearSizeCompatibleBPPRelaxed(const ImageInfo& lhs, const ImageInfo& rhs,
1041 u32 lhs_level, u32 rhs_level) noexcept {
1042 ASSERT(lhs.type != ImageType::Linear);
1043 ASSERT(rhs.type != ImageType::Linear);
1044 const auto lhs_bpp = BytesPerBlock(lhs.format);
1045 const auto rhs_bpp = BytesPerBlock(rhs.format);
1046 const Extent3D lhs_size = AdjustMipSize(lhs.size, lhs_level);
1047 const Extent3D rhs_size = AdjustMipSize(rhs.size, rhs_level);
1048 return Common::AlignUpLog2(lhs_size.width * lhs_bpp, GOB_SIZE_X_SHIFT) ==
1049 Common::AlignUpLog2(rhs_size.width * rhs_bpp, GOB_SIZE_X_SHIFT) &&
1050 Common::AlignUpLog2(lhs_size.height, GOB_SIZE_Y_SHIFT) ==
1051 Common::AlignUpLog2(rhs_size.height, GOB_SIZE_Y_SHIFT);
1052}
1053
1002bool IsPitchLinearSameSize(const ImageInfo& lhs, const ImageInfo& rhs, bool strict_size) noexcept { 1054bool IsPitchLinearSameSize(const ImageInfo& lhs, const ImageInfo& rhs, bool strict_size) noexcept {
1003 ASSERT(lhs.type == ImageType::Linear); 1055 ASSERT(lhs.type == ImageType::Linear);
1004 ASSERT(rhs.type == ImageType::Linear); 1056 ASSERT(rhs.type == ImageType::Linear);
@@ -1073,7 +1125,8 @@ std::optional<SubresourceBase> FindSubresource(const ImageInfo& candidate, const
1073 // Format checking is relaxed, but we still have to check for matching bytes per block. 1125 // Format checking is relaxed, but we still have to check for matching bytes per block.
1074 // This avoids creating a view for blits on UE4 titles where formats with different bytes 1126 // This avoids creating a view for blits on UE4 titles where formats with different bytes
1075 // per block are aliased. 1127 // per block are aliased.
1076 if (BytesPerBlock(existing.format) != BytesPerBlock(candidate.format)) { 1128 if (BytesPerBlock(existing.format) != BytesPerBlock(candidate.format) &&
1129 False(options & RelaxedOptions::FormatBpp)) {
1077 return std::nullopt; 1130 return std::nullopt;
1078 } 1131 }
1079 } else { 1132 } else {
@@ -1088,10 +1141,8 @@ std::optional<SubresourceBase> FindSubresource(const ImageInfo& candidate, const
1088 if (existing.type != candidate.type) { 1141 if (existing.type != candidate.type) {
1089 return std::nullopt; 1142 return std::nullopt;
1090 } 1143 }
1091 if (False(options & RelaxedOptions::Samples)) { 1144 if (False(options & RelaxedOptions::Samples) && existing.num_samples != candidate.num_samples) {
1092 if (existing.num_samples != candidate.num_samples) { 1145 return std::nullopt;
1093 return std::nullopt;
1094 }
1095 } 1146 }
1096 if (existing.resources.levels < candidate.resources.levels + base->level) { 1147 if (existing.resources.levels < candidate.resources.levels + base->level) {
1097 return std::nullopt; 1148 return std::nullopt;
@@ -1101,14 +1152,16 @@ std::optional<SubresourceBase> FindSubresource(const ImageInfo& candidate, const
1101 if (mip_depth < candidate.size.depth + base->layer) { 1152 if (mip_depth < candidate.size.depth + base->layer) {
1102 return std::nullopt; 1153 return std::nullopt;
1103 } 1154 }
1104 } else { 1155 } else if (existing.resources.layers < candidate.resources.layers + base->layer) {
1105 if (existing.resources.layers < candidate.resources.layers + base->layer) { 1156 return std::nullopt;
1106 return std::nullopt;
1107 }
1108 } 1157 }
1109 const bool strict_size = False(options & RelaxedOptions::Size); 1158 const bool strict_size = False(options & RelaxedOptions::Size);
1110 if (!IsBlockLinearSizeCompatible(existing, candidate, base->level, 0, strict_size)) { 1159 if (!IsBlockLinearSizeCompatible(existing, candidate, base->level, 0, strict_size)) {
1111 return std::nullopt; 1160 if (False(options & RelaxedOptions::FormatBpp)) {
1161 return std::nullopt;
1162 } else if (!IsBlockLinearSizeCompatibleBPPRelaxed(existing, candidate, base->level, 0)) {
1163 return std::nullopt;
1164 }
1112 } 1165 }
1113 // TODO: compare block sizes 1166 // TODO: compare block sizes
1114 return base; 1167 return base;
@@ -1120,6 +1173,31 @@ bool IsSubresource(const ImageInfo& candidate, const ImageBase& image, GPUVAddr
1120 .has_value(); 1173 .has_value();
1121} 1174}
1122 1175
1176bool IsSubCopy(const ImageInfo& candidate, const ImageBase& image, GPUVAddr candidate_addr) {
1177 const std::optional<SubresourceBase> base = image.TryFindBase(candidate_addr);
1178 if (!base) {
1179 return false;
1180 }
1181 const ImageInfo& existing = image.info;
1182 if (existing.resources.levels < candidate.resources.levels + base->level) {
1183 return false;
1184 }
1185 if (existing.type == ImageType::e3D) {
1186 const u32 mip_depth = std::max(1U, existing.size.depth << base->level);
1187 if (mip_depth < candidate.size.depth + base->layer) {
1188 return false;
1189 }
1190 } else {
1191 if (existing.resources.layers < candidate.resources.layers + base->layer) {
1192 return false;
1193 }
1194 }
1195 if (!IsBlockLinearSizeCompatibleBPPRelaxed(existing, candidate, base->level, 0)) {
1196 return false;
1197 }
1198 return true;
1199}
1200
1123void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst, 1201void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst,
1124 const ImageBase* src) { 1202 const ImageBase* src) {
1125 const auto original_dst_format = dst_info.format; 1203 const auto original_dst_format = dst_info.format;
diff --git a/src/video_core/texture_cache/util.h b/src/video_core/texture_cache/util.h
index d103db8ae..84aa6880d 100644
--- a/src/video_core/texture_cache/util.h
+++ b/src/video_core/texture_cache/util.h
@@ -56,6 +56,10 @@ struct OverlapResult {
56 SubresourceBase base, u32 up_scale = 1, 56 SubresourceBase base, u32 up_scale = 1,
57 u32 down_shift = 0); 57 u32 down_shift = 0);
58 58
59[[nodiscard]] std::vector<ImageCopy> MakeReinterpretImageCopies(const ImageInfo& src,
60 u32 up_scale = 1,
61 u32 down_shift = 0);
62
59[[nodiscard]] bool IsValidEntry(const Tegra::MemoryManager& gpu_memory, const TICEntry& config); 63[[nodiscard]] bool IsValidEntry(const Tegra::MemoryManager& gpu_memory, const TICEntry& config);
60 64
61[[nodiscard]] std::vector<BufferImageCopy> UnswizzleImage(Tegra::MemoryManager& gpu_memory, 65[[nodiscard]] std::vector<BufferImageCopy> UnswizzleImage(Tegra::MemoryManager& gpu_memory,
@@ -88,6 +92,9 @@ void SwizzleImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr, const Ima
88[[nodiscard]] bool IsPitchLinearSameSize(const ImageInfo& lhs, const ImageInfo& rhs, 92[[nodiscard]] bool IsPitchLinearSameSize(const ImageInfo& lhs, const ImageInfo& rhs,
89 bool strict_size) noexcept; 93 bool strict_size) noexcept;
90 94
95[[nodiscard]] bool IsBlockLinearSizeCompatibleBPPRelaxed(const ImageInfo& lhs, const ImageInfo& rhs,
96 u32 lhs_level, u32 rhs_level) noexcept;
97
91[[nodiscard]] std::optional<OverlapResult> ResolveOverlap(const ImageInfo& new_info, 98[[nodiscard]] std::optional<OverlapResult> ResolveOverlap(const ImageInfo& new_info,
92 GPUVAddr gpu_addr, VAddr cpu_addr, 99 GPUVAddr gpu_addr, VAddr cpu_addr,
93 const ImageBase& overlap, 100 const ImageBase& overlap,
@@ -106,6 +113,9 @@ void SwizzleImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr, const Ima
106 GPUVAddr candidate_addr, RelaxedOptions options, bool broken_views, 113 GPUVAddr candidate_addr, RelaxedOptions options, bool broken_views,
107 bool native_bgr); 114 bool native_bgr);
108 115
116[[nodiscard]] bool IsSubCopy(const ImageInfo& candidate, const ImageBase& image,
117 GPUVAddr candidate_addr);
118
109void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst, 119void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst,
110 const ImageBase* src); 120 const ImageBase* src);
111 121
diff --git a/src/video_core/textures/astc.cpp b/src/video_core/textures/astc.cpp
index e8d7c7863..4381eed1d 100644
--- a/src/video_core/textures/astc.cpp
+++ b/src/video_core/textures/astc.cpp
@@ -1656,8 +1656,8 @@ void Decompress(std::span<const uint8_t> data, uint32_t width, uint32_t height,
1656 const u32 rows = Common::DivideUp(height, block_height); 1656 const u32 rows = Common::DivideUp(height, block_height);
1657 const u32 cols = Common::DivideUp(width, block_width); 1657 const u32 cols = Common::DivideUp(width, block_width);
1658 1658
1659 Common::ThreadWorker workers{std::max(std::thread::hardware_concurrency(), 2U) / 2, 1659 static Common::ThreadWorker workers{std::max(std::thread::hardware_concurrency(), 2U) / 2,
1660 "ASTCDecompress"}; 1660 "ASTCDecompress"};
1661 1661
1662 for (u32 z = 0; z < depth; ++z) { 1662 for (u32 z = 0; z < depth; ++z) {
1663 const u32 depth_offset = z * height * width * 4; 1663 const u32 depth_offset = z * height * width * 4;
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 23d922e5d..48f1a3d14 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -409,6 +409,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
409 if (is_rdna2) { 409 if (is_rdna2) {
410 LOG_WARNING(Render_Vulkan, 410 LOG_WARNING(Render_Vulkan,
411 "RADV has broken VK_EXT_vertex_input_dynamic_state on RDNA2 hardware"); 411 "RADV has broken VK_EXT_vertex_input_dynamic_state on RDNA2 hardware");
412 features.vertex_input_dynamic_state.vertexInputDynamicState = false;
412 extensions.vertex_input_dynamic_state = false; 413 extensions.vertex_input_dynamic_state = false;
413 loaded_extensions.erase(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); 414 loaded_extensions.erase(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
414 } 415 }
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 06d982d9b..0f8c1e6a6 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -314,7 +314,7 @@ endif()
314create_target_directory_groups(yuzu) 314create_target_directory_groups(yuzu)
315 315
316target_link_libraries(yuzu PRIVATE common core input_common network video_core) 316target_link_libraries(yuzu PRIVATE common core input_common network video_core)
317target_link_libraries(yuzu PRIVATE Boost::boost glad Qt${QT_MAJOR_VERSION}::Widgets) 317target_link_libraries(yuzu PRIVATE Boost::headers glad Qt${QT_MAJOR_VERSION}::Widgets)
318target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) 318target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
319 319
320target_link_libraries(yuzu PRIVATE Vulkan::Headers) 320target_link_libraries(yuzu PRIVATE Vulkan::Headers)
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index bfed2d038..bb731276e 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -707,6 +707,7 @@ void Config::ReadRendererValues() {
707 ReadGlobalSetting(Settings::values.use_asynchronous_gpu_emulation); 707 ReadGlobalSetting(Settings::values.use_asynchronous_gpu_emulation);
708 ReadGlobalSetting(Settings::values.nvdec_emulation); 708 ReadGlobalSetting(Settings::values.nvdec_emulation);
709 ReadGlobalSetting(Settings::values.accelerate_astc); 709 ReadGlobalSetting(Settings::values.accelerate_astc);
710 ReadGlobalSetting(Settings::values.async_astc);
710 ReadGlobalSetting(Settings::values.use_vsync); 711 ReadGlobalSetting(Settings::values.use_vsync);
711 ReadGlobalSetting(Settings::values.shader_backend); 712 ReadGlobalSetting(Settings::values.shader_backend);
712 ReadGlobalSetting(Settings::values.use_asynchronous_shaders); 713 ReadGlobalSetting(Settings::values.use_asynchronous_shaders);
@@ -1348,6 +1349,7 @@ void Config::SaveRendererValues() {
1348 static_cast<u32>(Settings::values.nvdec_emulation.GetDefault()), 1349 static_cast<u32>(Settings::values.nvdec_emulation.GetDefault()),
1349 Settings::values.nvdec_emulation.UsingGlobal()); 1350 Settings::values.nvdec_emulation.UsingGlobal());
1350 WriteGlobalSetting(Settings::values.accelerate_astc); 1351 WriteGlobalSetting(Settings::values.accelerate_astc);
1352 WriteGlobalSetting(Settings::values.async_astc);
1351 WriteGlobalSetting(Settings::values.use_vsync); 1353 WriteGlobalSetting(Settings::values.use_vsync);
1352 WriteSetting(QString::fromStdString(Settings::values.shader_backend.GetLabel()), 1354 WriteSetting(QString::fromStdString(Settings::values.shader_backend.GetLabel()),
1353 static_cast<u32>(Settings::values.shader_backend.GetValue(global)), 1355 static_cast<u32>(Settings::values.shader_backend.GetValue(global)),
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp
index 7ab5d5bf5..59fb1b334 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.cpp
+++ b/src/yuzu/configuration/configure_graphics_advanced.cpp
@@ -23,11 +23,13 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
23 const bool runtime_lock = !system.IsPoweredOn(); 23 const bool runtime_lock = !system.IsPoweredOn();
24 ui->use_vsync->setEnabled(runtime_lock); 24 ui->use_vsync->setEnabled(runtime_lock);
25 ui->renderer_force_max_clock->setEnabled(runtime_lock); 25 ui->renderer_force_max_clock->setEnabled(runtime_lock);
26 ui->async_astc->setEnabled(runtime_lock);
26 ui->use_asynchronous_shaders->setEnabled(runtime_lock); 27 ui->use_asynchronous_shaders->setEnabled(runtime_lock);
27 ui->anisotropic_filtering_combobox->setEnabled(runtime_lock); 28 ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
28 29
29 ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue()); 30 ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue());
30 ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue()); 31 ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
32 ui->async_astc->setChecked(Settings::values.async_astc.GetValue());
31 ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue()); 33 ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
32 ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue()); 34 ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
33 ui->use_pessimistic_flushes->setChecked(Settings::values.use_pessimistic_flushes.GetValue()); 35 ui->use_pessimistic_flushes->setChecked(Settings::values.use_pessimistic_flushes.GetValue());
@@ -58,6 +60,8 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
58 ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy, 60 ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
59 ui->anisotropic_filtering_combobox); 61 ui->anisotropic_filtering_combobox);
60 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, use_vsync); 62 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, use_vsync);
63 ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_astc, ui->async_astc,
64 async_astc);
61 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders, 65 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
62 ui->use_asynchronous_shaders, 66 ui->use_asynchronous_shaders,
63 use_asynchronous_shaders); 67 use_asynchronous_shaders);
@@ -89,6 +93,7 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
89 ui->renderer_force_max_clock->setEnabled( 93 ui->renderer_force_max_clock->setEnabled(
90 Settings::values.renderer_force_max_clock.UsingGlobal()); 94 Settings::values.renderer_force_max_clock.UsingGlobal());
91 ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal()); 95 ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal());
96 ui->async_astc->setEnabled(Settings::values.async_astc.UsingGlobal());
92 ui->use_asynchronous_shaders->setEnabled( 97 ui->use_asynchronous_shaders->setEnabled(
93 Settings::values.use_asynchronous_shaders.UsingGlobal()); 98 Settings::values.use_asynchronous_shaders.UsingGlobal());
94 ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal()); 99 ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal());
@@ -106,6 +111,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
106 Settings::values.renderer_force_max_clock, 111 Settings::values.renderer_force_max_clock,
107 renderer_force_max_clock); 112 renderer_force_max_clock);
108 ConfigurationShared::SetColoredTristate(ui->use_vsync, Settings::values.use_vsync, use_vsync); 113 ConfigurationShared::SetColoredTristate(ui->use_vsync, Settings::values.use_vsync, use_vsync);
114 ConfigurationShared::SetColoredTristate(ui->async_astc, Settings::values.async_astc,
115 async_astc);
109 ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders, 116 ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders,
110 Settings::values.use_asynchronous_shaders, 117 Settings::values.use_asynchronous_shaders,
111 use_asynchronous_shaders); 118 use_asynchronous_shaders);
diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h
index df557d585..bf1b04749 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.h
+++ b/src/yuzu/configuration/configure_graphics_advanced.h
@@ -38,6 +38,7 @@ private:
38 38
39 ConfigurationShared::CheckState renderer_force_max_clock; 39 ConfigurationShared::CheckState renderer_force_max_clock;
40 ConfigurationShared::CheckState use_vsync; 40 ConfigurationShared::CheckState use_vsync;
41 ConfigurationShared::CheckState async_astc;
41 ConfigurationShared::CheckState use_asynchronous_shaders; 42 ConfigurationShared::CheckState use_asynchronous_shaders;
42 ConfigurationShared::CheckState use_fast_gpu_time; 43 ConfigurationShared::CheckState use_fast_gpu_time;
43 ConfigurationShared::CheckState use_pessimistic_flushes; 44 ConfigurationShared::CheckState use_pessimistic_flushes;
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui
index 061885e30..a7dbdc18c 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.ui
+++ b/src/yuzu/configuration/configure_graphics_advanced.ui
@@ -90,6 +90,16 @@
90 </widget> 90 </widget>
91 </item> 91 </item>
92 <item> 92 <item>
93 <widget class="QCheckBox" name="async_astc">
94 <property name="toolTip">
95 <string>Enables asynchronous ASTC texture decoding, which may reduce load time stutter. This feature is experimental.</string>
96 </property>
97 <property name="text">
98 <string>Decode ASTC textures asynchronously (Hack)</string>
99 </property>
100 </widget>
101 </item>
102 <item>
93 <widget class="QCheckBox" name="use_asynchronous_shaders"> 103 <widget class="QCheckBox" name="use_asynchronous_shaders">
94 <property name="toolTip"> 104 <property name="toolTip">
95 <string>Enables asynchronous shader compilation, which may reduce shader stutter. This feature is experimental.</string> 105 <string>Enables asynchronous shader compilation, which may reduce shader stutter. This feature is experimental.</string>
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index f233b065e..c092507f4 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -91,6 +91,9 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
91#include "common/microprofile.h" 91#include "common/microprofile.h"
92#include "common/scm_rev.h" 92#include "common/scm_rev.h"
93#include "common/scope_exit.h" 93#include "common/scope_exit.h"
94#ifdef _WIN32
95#include "common/windows/timer_resolution.h"
96#endif
94#ifdef ARCHITECTURE_x86_64 97#ifdef ARCHITECTURE_x86_64
95#include "common/x64/cpu_detect.h" 98#include "common/x64/cpu_detect.h"
96#endif 99#endif
@@ -377,6 +380,12 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan
377 LOG_INFO(Frontend, "Host RAM: {:.2f} GiB", 380 LOG_INFO(Frontend, "Host RAM: {:.2f} GiB",
378 Common::GetMemInfo().TotalPhysicalMemory / f64{1_GiB}); 381 Common::GetMemInfo().TotalPhysicalMemory / f64{1_GiB});
379 LOG_INFO(Frontend, "Host Swap: {:.2f} GiB", Common::GetMemInfo().TotalSwapMemory / f64{1_GiB}); 382 LOG_INFO(Frontend, "Host Swap: {:.2f} GiB", Common::GetMemInfo().TotalSwapMemory / f64{1_GiB});
383#ifdef _WIN32
384 LOG_INFO(Frontend, "Host Timer Resolution: {:.4f} ms",
385 std::chrono::duration_cast<std::chrono::duration<f64, std::milli>>(
386 Common::Windows::SetCurrentTimerResolutionToMaximum())
387 .count());
388#endif
380 UpdateWindowTitle(); 389 UpdateWindowTitle();
381 390
382 show(); 391 show();
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 3b6dce296..464da3231 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -324,6 +324,7 @@ void Config::ReadValues() {
324 ReadSetting("Renderer", Settings::values.use_asynchronous_shaders); 324 ReadSetting("Renderer", Settings::values.use_asynchronous_shaders);
325 ReadSetting("Renderer", Settings::values.nvdec_emulation); 325 ReadSetting("Renderer", Settings::values.nvdec_emulation);
326 ReadSetting("Renderer", Settings::values.accelerate_astc); 326 ReadSetting("Renderer", Settings::values.accelerate_astc);
327 ReadSetting("Renderer", Settings::values.async_astc);
327 ReadSetting("Renderer", Settings::values.use_fast_gpu_time); 328 ReadSetting("Renderer", Settings::values.use_fast_gpu_time);
328 ReadSetting("Renderer", Settings::values.use_pessimistic_flushes); 329 ReadSetting("Renderer", Settings::values.use_pessimistic_flushes);
329 ReadSetting("Renderer", Settings::values.use_vulkan_driver_pipeline_cache); 330 ReadSetting("Renderer", Settings::values.use_vulkan_driver_pipeline_cache);
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index cf3cc4c4e..20e403400 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -342,6 +342,10 @@ nvdec_emulation =
342# 0: Off, 1 (default): On 342# 0: Off, 1 (default): On
343accelerate_astc = 343accelerate_astc =
344 344
345# Decode ASTC textures asynchronously.
346# 0 (default): Off, 1: On
347async_astc =
348
345# Turns on the speed limiter, which will limit the emulation speed to the desired speed limit value 349# Turns on the speed limiter, which will limit the emulation speed to the desired speed limit value
346# 0: Off, 1: On (default) 350# 0: Off, 1: On (default)
347use_speed_limit = 351use_speed_limit =
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 77edd58ca..5f39ece32 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -42,6 +42,8 @@
42#include <windows.h> 42#include <windows.h>
43 43
44#include <shellapi.h> 44#include <shellapi.h>
45
46#include "common/windows/timer_resolution.h"
45#endif 47#endif
46 48
47#undef _UNICODE 49#undef _UNICODE
@@ -314,6 +316,8 @@ int main(int argc, char** argv) {
314 316
315#ifdef _WIN32 317#ifdef _WIN32
316 LocalFree(argv_w); 318 LocalFree(argv_w);
319
320 Common::Windows::SetCurrentTimerResolutionToMaximum();
317#endif 321#endif
318 322
319 MicroProfileOnThreadCreate("EmuThread"); 323 MicroProfileOnThreadCreate("EmuThread");