aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/core.h
blob: 91e78672efd47508a47f36d700d2dcb973a8b419 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <cstddef>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <vector>

#include "common/common_types.h"
#include "core/file_sys/vfs_types.h"

namespace Core::Frontend {
class EmuWindow;
} // namespace Core::Frontend

namespace FileSys {
class ContentProvider;
class ContentProviderUnion;
enum class ContentProviderUnionSlot;
class VfsFilesystem;
} // namespace FileSys

namespace Kernel {
class GlobalSchedulerContext;
class KernelCore;
class PhysicalCore;
class KProcess;
class KScheduler;
} // namespace Kernel

namespace Loader {
class AppLoader;
enum class ResultStatus : u16;
} // namespace Loader

namespace Core::Memory {
struct CheatEntry;
class Memory;
} // namespace Core::Memory

namespace Service {

namespace AM::Applets {
struct AppletFrontendSet;
class AppletManager;
} // namespace AM::Applets

namespace APM {
class Controller;
}

namespace FileSystem {
class FileSystemController;
} // namespace FileSystem

namespace Glue {
class ARPManager;
}

class ServerManager;

namespace SM {
class ServiceManager;
} // namespace SM

namespace Time {
class TimeManager;
} // namespace Time

} // namespace Service

namespace Tegra {
class DebugContext;
class GPU;
namespace Host1x {
class Host1x;
} // namespace Host1x
} // namespace Tegra

namespace VideoCore {
class RendererBase;
} // namespace VideoCore

namespace AudioCore {
class AudioCore;
} // namespace AudioCore

namespace Core::Timing {
class CoreTiming;
}

namespace Core::HID {
class HIDCore;
}

namespace Network {
class RoomNetwork;
}

namespace Core {

class ARM_Interface;
class CpuManager;
class Debugger;
class DeviceMemory;
class ExclusiveMonitor;
class SpeedLimiter;
class PerfStats;
class Reporter;
class TelemetrySession;

struct PerfStatsResults;

FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
                                         const std::string& path);

/// Enumeration representing the return values of the System Initialize and Load process.
enum class SystemResultStatus : u32 {
    Success,             ///< Succeeded
    ErrorNotInitialized, ///< Error trying to use core prior to initialization
    ErrorGetLoader,      ///< Error finding the correct application loader
    ErrorSystemFiles,    ///< Error in finding system files
    ErrorSharedFont,     ///< Error in finding shared font
    ErrorVideoCore,      ///< Error in the video core
    ErrorUnknown,        ///< Any other error
    ErrorLoader,         ///< The base for loader errors (too many to repeat)
};

class System {
public:
    using CurrentBuildProcessID = std::array<u8, 0x20>;

    explicit System();

    ~System();

    System(const System&) = delete;
    System& operator=(const System&) = delete;

    System(System&&) = delete;
    System& operator=(System&&) = delete;

    /**
     * Initializes the system
     * This function will initialize core functionaility used for system emulation
     */
    void Initialize();

    /**
     * Run the OS and Application
     * This function will start emulation and run the relevant devices
     */
    void Run();

    /**
     * Pause the OS and Application
     * This function will pause emulation and stop the relevant devices
     */
    void Pause();

    /// Check if the core is currently paused.
    [[nodiscard]] bool IsPaused() const;

    /**
     * Invalidate the CPU instruction caches
     * This function should only be used by GDB Stub to support breakpoints, memory updates and
     * step/continue commands.
     */
    void InvalidateCpuInstructionCaches();

    void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);

    /// Shutdown the main emulated process.
    void ShutdownMainProcess();

    /// Check if the core is shutting down.
    [[nodiscard]] bool IsShuttingDown() const;

    /// Set the shutting down state.
    void SetShuttingDown(bool shutting_down);

    /// Forcibly detach the debugger if it is running.
    void DetachDebugger();

    std::unique_lock<std::mutex> StallApplication();
    void UnstallApplication();

    /**
     * Initialize the debugger.
     */
    void InitializeDebugger();

    /**
     * Load an executable application.
     * @param emu_window Reference to the host-system window used for video output and keyboard
     *                   input.
     * @param filepath String path to the executable application to load on the host file system.
     * @param program_index Specifies the index within the container of the program to launch.
     * @returns SystemResultStatus code, indicating if the operation succeeded.
     */
    [[nodiscard]] SystemResultStatus Load(Frontend::EmuWindow& emu_window,
                                          const std::string& filepath, u64 program_id = 0,
                                          std::size_t program_index = 0);

    /**
     * Indicates if the emulated system is powered on (all subsystems initialized and able to run an
     * application).
     * @returns True if the emulated system is powered on, otherwise false.
     */
    [[nodiscard]] bool IsPoweredOn() const;

    /// Gets a reference to the telemetry session for this emulation session.
    [[nodiscard]] Core::TelemetrySession& TelemetrySession();

    /// Gets a reference to the telemetry session for this emulation session.
    [[nodiscard]] const Core::TelemetrySession& TelemetrySession() const;

    /// Prepare the core emulation for a reschedule
    void PrepareReschedule(u32 core_index);

    /// Gets and resets core performance statistics
    [[nodiscard]] PerfStatsResults GetAndResetPerfStats();

    /// Gets an ARM interface to the CPU core that is currently running
    [[nodiscard]] ARM_Interface& CurrentArmInterface();

    /// Gets an ARM interface to the CPU core that is currently running
    [[nodiscard]] const ARM_Interface& CurrentArmInterface() const;

    /// Gets the physical core for the CPU core that is currently running
    [[nodiscard]] Kernel::PhysicalCore& CurrentPhysicalCore();

    /// Gets the physical core for the CPU core that is currently running
    [[nodiscard]] const Kernel::PhysicalCore& CurrentPhysicalCore() const;

    /// Gets a reference to an ARM interface for the CPU core with the specified index
    [[nodiscard]] ARM_Interface& ArmInterface(std::size_t core_index);

    /// Gets a const reference to an ARM interface from the CPU core with the specified index
    [[nodiscard]] const ARM_Interface& ArmInterface(std::size_t core_index) const;

    /// Gets a reference to the underlying CPU manager.
    [[nodiscard]] CpuManager& GetCpuManager();

    /// Gets a const reference to the underlying CPU manager
    [[nodiscard]] const CpuManager& GetCpuManager() const;

    /// Gets a reference to the exclusive monitor
    [[nodiscard]] ExclusiveMonitor& Monitor();

    /// Gets a constant reference to the exclusive monitor
    [[nodiscard]] const ExclusiveMonitor& Monitor() const;

    /// Gets a mutable reference to the system memory instance.
    [[nodiscard]] Core::Memory::Memory& Memory();

    /// Gets a constant reference to the system memory instance.
    [[nodiscard]] const Core::Memory::Memory& Memory() const;

    /// Gets a mutable reference to the GPU interface
    [[nodiscard]] Tegra::GPU& GPU();

    /// Gets an immutable reference to the GPU interface.
    [[nodiscard]] const Tegra::GPU& GPU() const;

    /// Gets a mutable reference to the Host1x interface
    [[nodiscard]] Tegra::Host1x::Host1x& Host1x();

    /// Gets an immutable reference to the Host1x interface.
    [[nodiscard]] const Tegra::Host1x::Host1x& Host1x() const;

    /// Gets a mutable reference to the renderer.
    [[nodiscard]] VideoCore::RendererBase& Renderer();

    /// Gets an immutable reference to the renderer.
    [[nodiscard]] const VideoCore::RendererBase& Renderer() const;

    /// Gets a mutable reference to the audio interface
    [[nodiscard]] AudioCore::AudioCore& AudioCore();

    /// Gets an immutable reference to the audio interface.
    [[nodiscard]] const AudioCore::AudioCore& AudioCore() const;

    /// Gets the global scheduler
    [[nodiscard]] Kernel::GlobalSchedulerContext& GlobalSchedulerContext();

    /// Gets the global scheduler
    [[nodiscard]] const Kernel::GlobalSchedulerContext& GlobalSchedulerContext() const;

    /// Gets the manager for the guest device memory
    [[nodiscard]] Core::DeviceMemory& DeviceMemory();

    /// Gets the manager for the guest device memory
    [[nodiscard]] const Core::DeviceMemory& DeviceMemory() const;

    /// Provides a pointer to the application process
    [[nodiscard]] Kernel::KProcess* ApplicationProcess();

    /// Provides a constant pointer to the application process.
    [[nodiscard]] const Kernel::KProcess* ApplicationProcess() const;

    /// Provides a reference to the core timing instance.
    [[nodiscard]] Timing::CoreTiming& CoreTiming();

    /// Provides a constant reference to the core timing instance.
    [[nodiscard]] const Timing::CoreTiming& CoreTiming() const;

    /// Provides a reference to the kernel instance.
    [[nodiscard]] Kernel::KernelCore& Kernel();

    /// Provides a constant reference to the kernel instance.
    [[nodiscard]] const Kernel::KernelCore& Kernel() const;

    /// Gets a mutable reference to the HID interface.
    [[nodiscard]] HID::HIDCore& HIDCore();

    /// Gets an immutable reference to the HID interface.
    [[nodiscard]] const HID::HIDCore& HIDCore() const;

    /// Provides a reference to the internal PerfStats instance.
    [[nodiscard]] Core::PerfStats& GetPerfStats();

    /// Provides a constant reference to the internal PerfStats instance.
    [[nodiscard]] const Core::PerfStats& GetPerfStats() const;

    /// Provides a reference to the speed limiter;
    [[nodiscard]] Core::SpeedLimiter& SpeedLimiter();

    /// Provides a constant reference to the speed limiter
    [[nodiscard]] const Core::SpeedLimiter& SpeedLimiter() const;

    [[nodiscard]] u64 GetApplicationProcessProgramID() const;

    /// Gets the name of the current game
    [[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const;

    void SetStatus(SystemResultStatus new_status, const char* details);

    [[nodiscard]] const std::string& GetStatusDetails() const;

    [[nodiscard]] Loader::AppLoader& GetAppLoader();
    [[nodiscard]] const Loader::AppLoader& GetAppLoader() const;

    [[nodiscard]] Service::SM::ServiceManager& ServiceManager();
    [[nodiscard]] const Service::SM::ServiceManager& ServiceManager() const;

    void SetFilesystem(FileSys::VirtualFilesystem vfs);

    [[nodiscard]] FileSys::VirtualFilesystem GetFilesystem() const;

    void RegisterCheatList(const std::vector<Memory::CheatEntry>& list,
                           const std::array<u8, 0x20>& build_id, VAddr main_region_begin,
                           u64 main_region_size);

    void SetAppletFrontendSet(Service::AM::Applets::AppletFrontendSet&& set);
    void SetDefaultAppletFrontendSet();

    [[nodiscard]] Service::AM::Applets::AppletManager& GetAppletManager();
    [[nodiscard]] const Service::AM::Applets::AppletManager& GetAppletManager() const;

    void SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider);

    [[nodiscard]] FileSys::ContentProvider& GetContentProvider();
    [[nodiscard]] const FileSys::ContentProvider& GetContentProvider() const;

    [[nodiscard]] Service::FileSystem::FileSystemController& GetFileSystemController();
    [[nodiscard]] const Service::FileSystem::FileSystemController& GetFileSystemController() const;

    void RegisterContentProvider(FileSys::ContentProviderUnionSlot slot,
                                 FileSys::ContentProvider* provider);

    void ClearContentProvider(FileSys::ContentProviderUnionSlot slot);

    [[nodiscard]] const Reporter& GetReporter() const;

    [[nodiscard]] Service::Glue::ARPManager& GetARPManager();
    [[nodiscard]] const Service::Glue::ARPManager& GetARPManager() const;

    [[nodiscard]] Service::APM::Controller& GetAPMController();
    [[nodiscard]] const Service::APM::Controller& GetAPMController() const;

    [[nodiscard]] Service::Time::TimeManager& GetTimeManager();
    [[nodiscard]] const Service::Time::TimeManager& GetTimeManager() const;

    [[nodiscard]] Core::Debugger& GetDebugger();
    [[nodiscard]] const Core::Debugger& GetDebugger() const;

    /// Gets a mutable reference to the Room Network.
    [[nodiscard]] Network::RoomNetwork& GetRoomNetwork();

    /// Gets an immutable reference to the Room Network.
    [[nodiscard]] const Network::RoomNetwork& GetRoomNetwork() const;

    void SetExitLock(bool locked);
    [[nodiscard]] bool GetExitLock() const;

    void SetApplicationProcessBuildID(const CurrentBuildProcessID& id);
    [[nodiscard]] const CurrentBuildProcessID& GetApplicationProcessBuildID() const;

    /// Register a host thread as an emulated CPU Core.
    void RegisterCoreThread(std::size_t id);

    /// Register a host thread as an auxiliary thread.
    void RegisterHostThread();

    /// Enter Dynarmic Microprofile
    void EnterDynarmicProfile();

    /// Exit Dynarmic Microprofile
    void ExitDynarmicProfile();

    /// Tells if system is running on multicore.
    [[nodiscard]] bool IsMulticore() const;

    /// Tells if the system debugger is enabled.
    [[nodiscard]] bool DebuggerEnabled() const;

    /// Runs a server instance until shutdown.
    void RunServer(std::unique_ptr<Service::ServerManager>&& server_manager);

    /// Type used for the frontend to designate a callback for System to re-launch the application
    /// using a specified program index.
    using ExecuteProgramCallback = std::function<void(std::size_t)>;

    /**
     * Registers a callback from the frontend for System to re-launch the application using a
     * specified program index.
     * @param callback Callback from the frontend to relaunch the application.
     */
    void RegisterExecuteProgramCallback(ExecuteProgramCallback&& callback);

    /**
     * Instructs the frontend to re-launch the application using the specified program_index.
     * @param program_index Specifies the index within the application of the program to launch.
     */
    void ExecuteProgram(std::size_t program_index);

    /// Type used for the frontend to designate a callback for System to exit the application.
    using ExitCallback = std::function<void()>;

    /**
     * Registers a callback from the frontend for System to exit the application.
     * @param callback Callback from the frontend to exit the application.
     */
    void RegisterExitCallback(ExitCallback&& callback);

    /// Instructs the frontend to exit the application.
    void Exit();

    /// Applies any changes to settings to this core instance.
    void ApplySettings();

private:
    struct Impl;
    std::unique_ptr<Impl> impl;
};

} // namespace Core