mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-11-03 23:28:48 +00:00 
			
		
		
		
	Kernel: Convert Event to not use Handles
This commit is contained in:
		
							parent
							
								
									ad80ff1e32
								
							
						
					
					
						commit
						d52d859936
					
				
					 10 changed files with 153 additions and 154 deletions
				
			
		| 
						 | 
					@ -14,78 +14,37 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kernel {
 | 
					namespace Kernel {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Event : public WaitObject {
 | 
					ResultVal<SharedPtr<Event>> Event::Create(ResetType reset_type, std::string name) {
 | 
				
			||||||
public:
 | 
					    SharedPtr<Event> evt(new Event);
 | 
				
			||||||
    std::string GetTypeName() const override { return "Event"; }
 | 
					    // TOOD(yuriks): Don't create Handle (see Thread::Create())
 | 
				
			||||||
    std::string GetName() const override { return name; }
 | 
					    CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(evt));
 | 
				
			||||||
 | 
					 | 
				
			||||||
    static const HandleType HANDLE_TYPE = HandleType::Event;
 | 
					 | 
				
			||||||
    HandleType GetHandleType() const override { return HANDLE_TYPE; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ResetType intitial_reset_type;          ///< ResetType specified at Event initialization
 | 
					 | 
				
			||||||
    ResetType reset_type;                   ///< Current ResetType
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool signaled;                          ///< Whether the event has already been signaled
 | 
					 | 
				
			||||||
    std::string name;                       ///< Name of event (optional)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool ShouldWait() override {
 | 
					 | 
				
			||||||
        return !signaled;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Acquire() override {
 | 
					 | 
				
			||||||
        _assert_msg_(Kernel, !ShouldWait(), "object unavailable!");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Release the event if it's not sticky...
 | 
					 | 
				
			||||||
        if (reset_type != RESETTYPE_STICKY)
 | 
					 | 
				
			||||||
            signaled = false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ResultCode SignalEvent(const Handle handle) {
 | 
					 | 
				
			||||||
    Event* evt = g_handle_table.Get<Event>(handle).get();
 | 
					 | 
				
			||||||
    if (evt == nullptr)
 | 
					 | 
				
			||||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    evt->signaled = true;
 | 
					 | 
				
			||||||
    evt->WakeupAllWaitingThreads();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return RESULT_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ResultCode ClearEvent(Handle handle) {
 | 
					 | 
				
			||||||
    Event* evt = g_handle_table.Get<Event>(handle).get();
 | 
					 | 
				
			||||||
    if (evt == nullptr)
 | 
					 | 
				
			||||||
        return InvalidHandle(ErrorModule::Kernel);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    evt->signaled = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return RESULT_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Creates an event
 | 
					 | 
				
			||||||
 * @param handle Reference to handle for the newly created mutex
 | 
					 | 
				
			||||||
 * @param reset_type ResetType describing how to create event
 | 
					 | 
				
			||||||
 * @param name Optional name of event
 | 
					 | 
				
			||||||
 * @return Newly created Event object
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static Event* CreateEvent(Handle& handle, const ResetType reset_type, const std::string& name) {
 | 
					 | 
				
			||||||
    Event* evt = new Event;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // TOOD(yuriks): Fix error reporting
 | 
					 | 
				
			||||||
    handle = Kernel::g_handle_table.Create(evt).ValueOr(INVALID_HANDLE);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    evt->signaled = false;
 | 
					    evt->signaled = false;
 | 
				
			||||||
    evt->reset_type = evt->intitial_reset_type = reset_type;
 | 
					    evt->reset_type = evt->intitial_reset_type = reset_type;
 | 
				
			||||||
    evt->name = name;
 | 
					    evt->name = std::move(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return evt;
 | 
					    return MakeResult<SharedPtr<Event>>(evt);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Handle CreateEvent(const ResetType reset_type, const std::string& name) {
 | 
					bool Event::ShouldWait() {
 | 
				
			||||||
    Handle handle;
 | 
					    return !signaled;
 | 
				
			||||||
    Event* evt = CreateEvent(handle, reset_type, name);
 | 
					}
 | 
				
			||||||
    return handle;
 | 
					
 | 
				
			||||||
 | 
					void Event::Acquire() {
 | 
				
			||||||
 | 
					    _assert_msg_(Kernel, !ShouldWait(), "object unavailable!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Release the event if it's not sticky...
 | 
				
			||||||
 | 
					    if (reset_type != RESETTYPE_STICKY)
 | 
				
			||||||
 | 
					        signaled = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Event::Signal() {
 | 
				
			||||||
 | 
					    signaled = true;
 | 
				
			||||||
 | 
					    WakeupAllWaitingThreads();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Event::Clear() {
 | 
				
			||||||
 | 
					    signaled = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,26 +11,35 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kernel {
 | 
					namespace Kernel {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					class Event : public WaitObject {
 | 
				
			||||||
 * Signals an event
 | 
					public:
 | 
				
			||||||
 * @param handle Handle to event to signal
 | 
					    /**
 | 
				
			||||||
 * @return Result of operation, 0 on success, otherwise error code
 | 
					     * Creates an event
 | 
				
			||||||
 */
 | 
					     * @param reset_type ResetType describing how to create event
 | 
				
			||||||
ResultCode SignalEvent(const Handle handle);
 | 
					     * @param name Optional name of event
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    static ResultVal<SharedPtr<Event>> Create(ResetType reset_type, std::string name = "Unknown");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					    std::string GetTypeName() const override { return "Event"; }
 | 
				
			||||||
 * Clears an event
 | 
					    std::string GetName() const override { return name; }
 | 
				
			||||||
 * @param handle Handle to event to clear
 | 
					 | 
				
			||||||
 * @return Result of operation, 0 on success, otherwise error code
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
ResultCode ClearEvent(Handle handle);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					    static const HandleType HANDLE_TYPE = HandleType::Event;
 | 
				
			||||||
 * Creates an event
 | 
					    HandleType GetHandleType() const override { return HANDLE_TYPE; }
 | 
				
			||||||
 * @param reset_type ResetType describing how to create event
 | 
					
 | 
				
			||||||
 * @param name Optional name of event
 | 
					    ResetType intitial_reset_type;          ///< ResetType specified at Event initialization
 | 
				
			||||||
 * @return Handle to newly created Event object
 | 
					    ResetType reset_type;                   ///< Current ResetType
 | 
				
			||||||
 */
 | 
					
 | 
				
			||||||
Handle CreateEvent(const ResetType reset_type, const std::string& name="Unknown");
 | 
					    bool signaled;                          ///< Whether the event has already been signaled
 | 
				
			||||||
 | 
					    std::string name;                       ///< Name of event (optional)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool ShouldWait() override;
 | 
				
			||||||
 | 
					    void Acquire() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void Signal();
 | 
				
			||||||
 | 
					    void Clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    Event() = default;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,8 +30,8 @@ static const VAddr SHARED_FONT_VADDR = 0x18000000;
 | 
				
			||||||
static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
 | 
					static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Kernel::SharedPtr<Kernel::Mutex> lock;
 | 
					static Kernel::SharedPtr<Kernel::Mutex> lock;
 | 
				
			||||||
static Handle notification_event_handle = 0; ///< APT notification event handle
 | 
					static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
 | 
				
			||||||
static Handle pause_event_handle = 0; ///< APT pause event handle
 | 
					static Kernel::SharedPtr<Kernel::Event> pause_event = 0; ///< APT pause event
 | 
				
			||||||
static std::vector<u8> shared_font;
 | 
					static std::vector<u8> shared_font;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Signals used by APT functions
 | 
					/// Signals used by APT functions
 | 
				
			||||||
| 
						 | 
					@ -68,14 +68,16 @@ enum class AppID : u32 {
 | 
				
			||||||
void Initialize(Service::Interface* self) {
 | 
					void Initialize(Service::Interface* self) {
 | 
				
			||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    notification_event_handle = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Notification");
 | 
					    // TODO(bunnei): Check if these are created in Initialize or on APT process startup.
 | 
				
			||||||
    pause_event_handle = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Pause");
 | 
					    notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification").MoveFrom();
 | 
				
			||||||
 | 
					    pause_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Pause").MoveFrom();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd_buff[3] = notification_event_handle;
 | 
					    cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom();
 | 
				
			||||||
    cmd_buff[4] = pause_event_handle;
 | 
					    cmd_buff[4] = Kernel::g_handle_table.Create(pause_event).MoveFrom();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Kernel::ClearEvent(notification_event_handle);
 | 
					    // TODO(bunnei): Check if these events are cleared/signaled every time Initialize is called.
 | 
				
			||||||
    Kernel::SignalEvent(pause_event_handle); // Fire start event
 | 
					    notification_event->Clear();
 | 
				
			||||||
 | 
					    pause_event->Signal(); // Fire start event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _assert_msg_(KERNEL, (nullptr != lock), "Cannot initialize without lock");
 | 
					    _assert_msg_(KERNEL, (nullptr != lock), "Cannot initialize without lock");
 | 
				
			||||||
    lock->Release();
 | 
					    lock->Release();
 | 
				
			||||||
| 
						 | 
					@ -94,7 +96,7 @@ void NotifyToWait(Service::Interface* self) {
 | 
				
			||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
    u32 app_id = cmd_buff[1];
 | 
					    u32 app_id = cmd_buff[1];
 | 
				
			||||||
    // TODO(Subv): Verify this, it seems to get SWKBD and Home Menu further.
 | 
					    // TODO(Subv): Verify this, it seems to get SWKBD and Home Menu further.
 | 
				
			||||||
    Kernel::SignalEvent(pause_event_handle);
 | 
					    pause_event->Signal();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
					    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
				
			||||||
    LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id);
 | 
					    LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id);
 | 
				
			||||||
| 
						 | 
					@ -104,10 +106,6 @@ void GetLockHandle(Service::Interface* self) {
 | 
				
			||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
    u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
 | 
					    u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (nullptr == lock) {
 | 
					 | 
				
			||||||
        // TODO(bunnei): Verify if this is created here or at application boot?
 | 
					 | 
				
			||||||
        lock = Kernel::Mutex::Create(false, "APT_U:Lock").MoveFrom();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
					    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Not sure what these parameters are used for, but retail apps check that they are 0 after
 | 
					    // Not sure what these parameters are used for, but retail apps check that they are 0 after
 | 
				
			||||||
| 
						 | 
					@ -520,7 +518,7 @@ Interface::Interface() {
 | 
				
			||||||
        shared_font_mem = nullptr;
 | 
					        shared_font_mem = nullptr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    lock = nullptr;
 | 
					    lock = Kernel::Mutex::Create(false, "APT_U:Lock").MoveFrom();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Register(FunctionTable, ARRAY_SIZE(FunctionTable));
 | 
					    Register(FunctionTable, ARRAY_SIZE(FunctionTable));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,8 +13,8 @@
 | 
				
			||||||
namespace DSP_DSP {
 | 
					namespace DSP_DSP {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u32 read_pipe_count    = 0;
 | 
					static u32 read_pipe_count    = 0;
 | 
				
			||||||
static Handle semaphore_event = 0;
 | 
					static Kernel::SharedPtr<Kernel::Event> semaphore_event;
 | 
				
			||||||
static Handle interrupt_event = 0;
 | 
					static Kernel::SharedPtr<Kernel::Event> interrupt_event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SignalInterrupt() {
 | 
					void SignalInterrupt() {
 | 
				
			||||||
    // TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated
 | 
					    // TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ void SignalInterrupt() {
 | 
				
			||||||
    // DSP interrupts, and trigger them at the appropriate times.
 | 
					    // DSP interrupts, and trigger them at the appropriate times.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (interrupt_event != 0)
 | 
					    if (interrupt_event != 0)
 | 
				
			||||||
        Kernel::SignalEvent(interrupt_event);
 | 
					        interrupt_event->Signal();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -78,8 +78,8 @@ void LoadComponent(Service::Interface* self) {
 | 
				
			||||||
void GetSemaphoreEventHandle(Service::Interface* self) {
 | 
					void GetSemaphoreEventHandle(Service::Interface* self) {
 | 
				
			||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd_buff[1] = 0; // No error
 | 
					    cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
				
			||||||
    cmd_buff[3] = semaphore_event; // Event handle
 | 
					    cmd_buff[3] = Kernel::g_handle_table.Create(semaphore_event).MoveFrom(); // Event handle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_WARNING(Service_DSP, "(STUBBED) called");
 | 
					    LOG_WARNING(Service_DSP, "(STUBBED) called");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -96,9 +96,16 @@ void GetSemaphoreEventHandle(Service::Interface* self) {
 | 
				
			||||||
void RegisterInterruptEvents(Service::Interface* self) {
 | 
					void RegisterInterruptEvents(Service::Interface* self) {
 | 
				
			||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    interrupt_event = static_cast<Handle>(cmd_buff[4]);
 | 
					    auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
 | 
				
			||||||
 | 
					    if (evt != nullptr) {
 | 
				
			||||||
 | 
					        interrupt_event = evt;
 | 
				
			||||||
 | 
					        cmd_buff[1] = 0; // No error
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        LOG_ERROR(Service_DSP, "called with invalid handle=%08X", cmd_buff[4]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd_buff[1] = 0; // No error
 | 
					        // TODO(yuriks): An error should be returned from SendSyncRequest, not in the cmdbuf
 | 
				
			||||||
 | 
					        cmd_buff[1] = -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LOG_WARNING(Service_DSP, "(STUBBED) called");
 | 
					    LOG_WARNING(Service_DSP, "(STUBBED) called");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -194,8 +201,9 @@ const Interface::FunctionInfo FunctionTable[] = {
 | 
				
			||||||
// Interface class
 | 
					// Interface class
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Interface::Interface() {
 | 
					Interface::Interface() {
 | 
				
			||||||
    semaphore_event = Kernel::CreateEvent(RESETTYPE_ONESHOT, "DSP_DSP::semaphore_event");
 | 
					    semaphore_event = Kernel::Event::Create(RESETTYPE_ONESHOT,
 | 
				
			||||||
    interrupt_event = 0;
 | 
					            "DSP_DSP::semaphore_event").MoveFrom();
 | 
				
			||||||
 | 
					    interrupt_event = nullptr;
 | 
				
			||||||
    read_pipe_count = 0;
 | 
					    read_pipe_count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Register(FunctionTable, ARRAY_SIZE(FunctionTable));
 | 
					    Register(FunctionTable, ARRAY_SIZE(FunctionTable));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,9 +22,12 @@ GraphicsDebugger g_debugger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace GSP_GPU {
 | 
					namespace GSP_GPU {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Handle g_interrupt_event = 0;   ///< Handle to event triggered when GSP interrupt has been signalled
 | 
					/// Event triggered when GSP interrupt has been signalled
 | 
				
			||||||
Kernel::SharedPtr<Kernel::SharedMemory> g_shared_memory; ///< GSP shared memoryings
 | 
					Kernel::SharedPtr<Kernel::Event> g_interrupt_event;
 | 
				
			||||||
u32 g_thread_id = 1;            ///< Thread index into interrupt relay queue, 1 is arbitrary
 | 
					/// GSP shared memoryings
 | 
				
			||||||
 | 
					Kernel::SharedPtr<Kernel::SharedMemory> g_shared_memory;
 | 
				
			||||||
 | 
					/// Thread index into interrupt relay queue, 1 is arbitrary
 | 
				
			||||||
 | 
					u32 g_thread_id = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Gets a pointer to a thread command buffer in GSP shared memory
 | 
					/// Gets a pointer to a thread command buffer in GSP shared memory
 | 
				
			||||||
static inline u8* GetCommandBuffer(u32 thread_id) {
 | 
					static inline u8* GetCommandBuffer(u32 thread_id) {
 | 
				
			||||||
| 
						 | 
					@ -181,10 +184,10 @@ static void FlushDataCache(Service::Interface* self) {
 | 
				
			||||||
static void RegisterInterruptRelayQueue(Service::Interface* self) {
 | 
					static void RegisterInterruptRelayQueue(Service::Interface* self) {
 | 
				
			||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
    u32 flags = cmd_buff[1];
 | 
					    u32 flags = cmd_buff[1];
 | 
				
			||||||
    g_interrupt_event = cmd_buff[3];
 | 
					 | 
				
			||||||
    g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem").MoveFrom();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _assert_msg_(GSP, (g_interrupt_event != 0), "handle is not valid!");
 | 
					    g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]);
 | 
				
			||||||
 | 
					    _assert_msg_(GSP, (g_interrupt_event != nullptr), "handle is not valid!");
 | 
				
			||||||
 | 
					    g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem").MoveFrom();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom();
 | 
					    Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -192,7 +195,7 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) {
 | 
				
			||||||
    cmd_buff[2] = g_thread_id++; // Thread ID
 | 
					    cmd_buff[2] = g_thread_id++; // Thread ID
 | 
				
			||||||
    cmd_buff[4] = shmem_handle; // GSP shared memory
 | 
					    cmd_buff[4] = shmem_handle; // GSP shared memory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Kernel::SignalEvent(g_interrupt_event); // TODO(bunnei): Is this correct?
 | 
					    g_interrupt_event->Signal(); // TODO(bunnei): Is this correct?
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -234,7 +237,7 @@ void SignalInterrupt(InterruptId interrupt_id) {
 | 
				
			||||||
            info->is_dirty = false;
 | 
					            info->is_dirty = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Kernel::SignalEvent(g_interrupt_event);
 | 
					    g_interrupt_event->Signal();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Executes the next GSP command
 | 
					/// Executes the next GSP command
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,11 +14,11 @@ namespace HID {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Kernel::SharedPtr<Kernel::SharedMemory> g_shared_mem = nullptr;
 | 
					Kernel::SharedPtr<Kernel::SharedMemory> g_shared_mem = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Handle g_event_pad_or_touch_1 = 0;
 | 
					Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_1;
 | 
				
			||||||
Handle g_event_pad_or_touch_2 = 0;
 | 
					Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_2;
 | 
				
			||||||
Handle g_event_accelerometer = 0;
 | 
					Kernel::SharedPtr<Kernel::Event> g_event_accelerometer;
 | 
				
			||||||
Handle g_event_gyroscope = 0;
 | 
					Kernel::SharedPtr<Kernel::Event> g_event_gyroscope;
 | 
				
			||||||
Handle g_event_debug_pad = 0;
 | 
					Kernel::SharedPtr<Kernel::Event> g_event_debug_pad;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Next Pad state update information
 | 
					// Next Pad state update information
 | 
				
			||||||
static PadState next_state = {{0}};
 | 
					static PadState next_state = {{0}};
 | 
				
			||||||
| 
						 | 
					@ -115,19 +115,21 @@ void PadUpdateComplete() {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Signal both handles when there's an update to Pad or touch
 | 
					    // Signal both handles when there's an update to Pad or touch
 | 
				
			||||||
    Kernel::SignalEvent(g_event_pad_or_touch_1);
 | 
					    g_event_pad_or_touch_1->Signal();
 | 
				
			||||||
    Kernel::SignalEvent(g_event_pad_or_touch_2);
 | 
					    g_event_pad_or_touch_2->Signal();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HIDInit() {
 | 
					void HIDInit() {
 | 
				
			||||||
    g_shared_mem = Kernel::SharedMemory::Create("HID:SharedMem").MoveFrom();
 | 
					    using namespace Kernel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_shared_mem = SharedMemory::Create("HID:SharedMem").MoveFrom();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create event handles
 | 
					    // Create event handles
 | 
				
			||||||
    g_event_pad_or_touch_1 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1");
 | 
					    g_event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1").MoveFrom();
 | 
				
			||||||
    g_event_pad_or_touch_2 = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2");
 | 
					    g_event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2").MoveFrom();
 | 
				
			||||||
    g_event_accelerometer = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID:EventAccelerometer");
 | 
					    g_event_accelerometer  = Event::Create(RESETTYPE_ONESHOT, "HID:EventAccelerometer").MoveFrom();
 | 
				
			||||||
    g_event_gyroscope = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID:EventGyroscope");
 | 
					    g_event_gyroscope      = Event::Create(RESETTYPE_ONESHOT, "HID:EventGyroscope").MoveFrom();
 | 
				
			||||||
    g_event_debug_pad = Kernel::CreateEvent(RESETTYPE_ONESHOT, "HID:EventDebugPad");
 | 
					    g_event_debug_pad      = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad").MoveFrom();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HIDShutdown() {
 | 
					void HIDShutdown() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kernel {
 | 
					namespace Kernel {
 | 
				
			||||||
    class SharedMemory;
 | 
					    class SharedMemory;
 | 
				
			||||||
 | 
					    class Event;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Service {
 | 
					namespace Service {
 | 
				
			||||||
| 
						 | 
					@ -20,11 +21,11 @@ namespace HID {
 | 
				
			||||||
extern Kernel::SharedPtr<Kernel::SharedMemory> g_shared_mem;
 | 
					extern Kernel::SharedPtr<Kernel::SharedMemory> g_shared_mem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Event handles
 | 
					// Event handles
 | 
				
			||||||
extern Handle g_event_pad_or_touch_1;
 | 
					extern Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_1;
 | 
				
			||||||
extern Handle g_event_pad_or_touch_2;
 | 
					extern Kernel::SharedPtr<Kernel::Event> g_event_pad_or_touch_2;
 | 
				
			||||||
extern Handle g_event_accelerometer;
 | 
					extern Kernel::SharedPtr<Kernel::Event> g_event_accelerometer;
 | 
				
			||||||
extern Handle g_event_gyroscope;
 | 
					extern Kernel::SharedPtr<Kernel::Event> g_event_gyroscope;
 | 
				
			||||||
extern Handle g_event_debug_pad;
 | 
					extern Kernel::SharedPtr<Kernel::Event> g_event_debug_pad;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Structure of a Pad controller state.
 | 
					 * Structure of a Pad controller state.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@
 | 
				
			||||||
#include "common/log.h"
 | 
					#include "common/log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core/hle/hle.h"
 | 
					#include "core/hle/hle.h"
 | 
				
			||||||
 | 
					#include "core/hle/kernel/event.h"
 | 
				
			||||||
#include "core/hle/kernel/shared_memory.h"
 | 
					#include "core/hle/kernel/shared_memory.h"
 | 
				
			||||||
#include "core/hle/service/hid/hid.h"
 | 
					#include "core/hle/service/hid/hid.h"
 | 
				
			||||||
#include "hid_user.h"
 | 
					#include "hid_user.h"
 | 
				
			||||||
| 
						 | 
					@ -49,11 +50,11 @@ void GetIPCHandles(Service::Interface* self) {
 | 
				
			||||||
    cmd_buff[1] = 0; // No error
 | 
					    cmd_buff[1] = 0; // No error
 | 
				
			||||||
    // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling)
 | 
					    // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling)
 | 
				
			||||||
    cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::g_shared_mem).MoveFrom();
 | 
					    cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::g_shared_mem).MoveFrom();
 | 
				
			||||||
    cmd_buff[4] = Service::HID::g_event_pad_or_touch_1;
 | 
					    cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_1).MoveFrom();
 | 
				
			||||||
    cmd_buff[5] = Service::HID::g_event_pad_or_touch_2;
 | 
					    cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_2).MoveFrom();
 | 
				
			||||||
    cmd_buff[6] = Service::HID::g_event_accelerometer;
 | 
					    cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::g_event_accelerometer).MoveFrom();
 | 
				
			||||||
    cmd_buff[7] = Service::HID::g_event_gyroscope;
 | 
					    cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::g_event_gyroscope).MoveFrom();
 | 
				
			||||||
    cmd_buff[8] = Service::HID::g_event_debug_pad;
 | 
					    cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::g_event_debug_pad).MoveFrom();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Interface::FunctionInfo FunctionTable[] = {
 | 
					const Interface::FunctionInfo FunctionTable[] = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SRV {
 | 
					namespace SRV {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Handle g_event_handle = 0;
 | 
					static Kernel::SharedPtr<Kernel::Event> event_handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void Initialize(Service::Interface* self) {
 | 
					static void Initialize(Service::Interface* self) {
 | 
				
			||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
| 
						 | 
					@ -23,11 +23,11 @@ static void GetProcSemaphore(Service::Interface* self) {
 | 
				
			||||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO(bunnei): Change to a semaphore once these have been implemented
 | 
					    // TODO(bunnei): Change to a semaphore once these have been implemented
 | 
				
			||||||
    g_event_handle = Kernel::CreateEvent(RESETTYPE_ONESHOT, "SRV:Event");
 | 
					    event_handle = Kernel::Event::Create(RESETTYPE_ONESHOT, "SRV:Event").MoveFrom();
 | 
				
			||||||
    Kernel::ClearEvent(g_event_handle);
 | 
					    event_handle->Clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd_buff[1] = 0; // No error
 | 
					    cmd_buff[1] = 0; // No error
 | 
				
			||||||
    cmd_buff[3] = g_event_handle;
 | 
					    cmd_buff[3] = Kernel::g_handle_table.Create(event_handle).MoveFrom();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void GetServiceHandle(Service::Interface* self) {
 | 
					static void GetServiceHandle(Service::Interface* self) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -447,11 +447,17 @@ static Result QueryMemory(void* info, void* out, u32 addr) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Create an event
 | 
					/// Create an event
 | 
				
			||||||
static Result CreateEvent(Handle* evt, u32 reset_type) {
 | 
					static Result CreateEvent(Handle* handle, u32 reset_type) {
 | 
				
			||||||
    *evt = Kernel::CreateEvent((ResetType)reset_type);
 | 
					    auto evt_res = Kernel::Event::Create(static_cast<ResetType>(reset_type));
 | 
				
			||||||
    LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X",
 | 
					    if (evt_res.Failed())
 | 
				
			||||||
        reset_type, *evt);
 | 
					        return evt_res.Code().raw;
 | 
				
			||||||
    return 0;
 | 
					    auto handle_res = Kernel::g_handle_table.Create(evt_res.MoveFrom());
 | 
				
			||||||
 | 
					    if (handle_res.Failed())
 | 
				
			||||||
 | 
					        return handle_res.Code().raw;
 | 
				
			||||||
 | 
					    *handle = handle_res.MoveFrom();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type, *handle);
 | 
				
			||||||
 | 
					    return RESULT_SUCCESS.raw;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Duplicates a kernel handle
 | 
					/// Duplicates a kernel handle
 | 
				
			||||||
| 
						 | 
					@ -465,16 +471,28 @@ static Result DuplicateHandle(Handle* out, Handle handle) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Signals an event
 | 
					/// Signals an event
 | 
				
			||||||
static Result SignalEvent(Handle evt) {
 | 
					static Result SignalEvent(Handle handle) {
 | 
				
			||||||
    LOG_TRACE(Kernel_SVC, "called event=0x%08X", evt);
 | 
					    LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto evt = Kernel::g_handle_table.Get<Kernel::Event>(handle);
 | 
				
			||||||
 | 
					    if (evt == nullptr)
 | 
				
			||||||
 | 
					        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    evt->Signal();
 | 
				
			||||||
    HLE::Reschedule(__func__);
 | 
					    HLE::Reschedule(__func__);
 | 
				
			||||||
    return Kernel::SignalEvent(evt).raw;
 | 
					    return RESULT_SUCCESS.raw;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Clears an event
 | 
					/// Clears an event
 | 
				
			||||||
static Result ClearEvent(Handle evt) {
 | 
					static Result ClearEvent(Handle handle) {
 | 
				
			||||||
    LOG_TRACE(Kernel_SVC, "called event=0x%08X", evt);
 | 
					    LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle);
 | 
				
			||||||
    return Kernel::ClearEvent(evt).raw;
 | 
					
 | 
				
			||||||
 | 
					    auto evt = Kernel::g_handle_table.Get<Kernel::Event>(handle);
 | 
				
			||||||
 | 
					    if (evt == nullptr)
 | 
				
			||||||
 | 
					        return InvalidHandle(ErrorModule::Kernel).raw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    evt->Clear();
 | 
				
			||||||
 | 
					    return RESULT_SUCCESS.raw;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Creates a timer
 | 
					/// Creates a timer
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue