mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-26 13:52:21 +00:00
htc: skeleton constructors for htcmisc
This commit is contained in:
parent
b925344c3b
commit
1f03b11dbc
12 changed files with 310 additions and 6 deletions
|
@ -140,6 +140,7 @@ namespace ams::impl {
|
|||
AMS_DEFINE_SYSTEM_THREAD(10, htc, Htcmisc);
|
||||
AMS_DEFINE_SYSTEM_THREAD(10, htc, HtcmiscReceive);
|
||||
AMS_DEFINE_SYSTEM_THREAD(10, htc, HtcmiscSend);
|
||||
AMS_DEFINE_SYSTEM_THREAD(10, htc, HtcObserver);
|
||||
|
||||
AMS_DEFINE_SYSTEM_THREAD(10, tma, BridgePcieDriver);
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "htc_htcmisc_impl.hpp"
|
||||
|
||||
namespace ams::htc::server {
|
||||
|
||||
namespace {
|
||||
|
||||
alignas(os::ThreadStackAlignment) u8 g_client_thread_stack[os::MemoryPageSize];
|
||||
alignas(os::ThreadStackAlignment) u8 g_server_thread_stack[os::MemoryPageSize];
|
||||
|
||||
}
|
||||
|
||||
HtcmiscImpl::HtcmiscImpl(htclow::HtclowManager *htclow_manager)
|
||||
: m_htclow_driver(htclow_manager, htclow::ModuleId::Htcmisc),
|
||||
m_driver_manager(std::addressof(m_htclow_driver)),
|
||||
m_rpc_client(std::addressof(m_htclow_driver), HtcmiscClientChannelId),
|
||||
m_rpc_server(std::addressof(m_htclow_driver), HtcmiscServerChannelId),
|
||||
m_cancel_event(os::EventClearMode_ManualClear),
|
||||
m_cancelled(false),
|
||||
m_connection_event(os::EventClearMode_ManualClear),
|
||||
m_client_connected(false),
|
||||
m_server_connected(false),
|
||||
m_connected(false),
|
||||
m_connection_mutex()
|
||||
{
|
||||
/* Create the client thread. */
|
||||
R_ABORT_UNLESS(os::CreateThread(std::addressof(m_client_thread), ClientThreadEntry, this, g_client_thread_stack, sizeof(g_client_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(htc, Htcmisc)));
|
||||
|
||||
/* Set the client thread name. */
|
||||
os::SetThreadNamePointer(std::addressof(m_client_thread), AMS_GET_SYSTEM_THREAD_NAME(htc, Htcmisc));
|
||||
|
||||
/* Start the client thread. */
|
||||
os::StartThread(std::addressof(m_client_thread));
|
||||
|
||||
/* Create the server thread. */
|
||||
R_ABORT_UNLESS(os::CreateThread(std::addressof(m_server_thread), ServerThreadEntry, this, g_server_thread_stack, sizeof(g_server_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(htc, Htcmisc)));
|
||||
|
||||
/* Set the server thread name. */
|
||||
os::SetThreadNamePointer(std::addressof(m_server_thread), AMS_GET_SYSTEM_THREAD_NAME(htc, Htcmisc));
|
||||
|
||||
/* Start the server thread. */
|
||||
os::StartThread(std::addressof(m_server_thread));
|
||||
}
|
||||
|
||||
HtcmiscImpl::~HtcmiscImpl() {
|
||||
/* Cancel ourselves. */
|
||||
this->Cancel();
|
||||
|
||||
/* Wait for our threads to be done, and destroy them. */
|
||||
os::WaitThread(std::addressof(m_client_thread));
|
||||
os::DestroyThread(std::addressof(m_client_thread));
|
||||
os::WaitThread(std::addressof(m_server_thread));
|
||||
os::DestroyThread(std::addressof(m_server_thread));
|
||||
}
|
||||
|
||||
void HtcmiscImpl::Cancel() {
|
||||
/* Set ourselves as cancelled. */
|
||||
m_cancelled = true;
|
||||
|
||||
/* Signal our cancel event. */
|
||||
m_cancel_event.Signal();
|
||||
}
|
||||
|
||||
void HtcmiscImpl::ClientThread() {
|
||||
AMS_ABORT("HtcmiscImpl::ClientThread");
|
||||
}
|
||||
|
||||
void HtcmiscImpl::ServerThread() {
|
||||
AMS_ABORT("HtcmiscImpl::ServerThread");
|
||||
}
|
||||
|
||||
}
|
|
@ -31,16 +31,24 @@ namespace ams::htc::server {
|
|||
rpc::HtcmiscRpcServer m_rpc_server;
|
||||
os::ThreadType m_client_thread;
|
||||
os::ThreadType m_server_thread;
|
||||
os::Event m_event_61200;
|
||||
u8 m_61228;
|
||||
os::Event m_event_61230;
|
||||
os::Event m_cancel_event;
|
||||
bool m_cancelled;
|
||||
os::Event m_connection_event;
|
||||
bool m_client_connected;
|
||||
bool m_server_connected;
|
||||
u8 m_6125A;
|
||||
bool m_connected;
|
||||
os::SdkMutex m_connection_mutex;
|
||||
private:
|
||||
static void ClientThreadEntry(void *arg) { static_cast<HtcmiscImpl *>(arg)->ClientThread(); }
|
||||
static void ServerThreadEntry(void *arg) { static_cast<HtcmiscImpl *>(arg)->ServerThread(); }
|
||||
|
||||
void ClientThread();
|
||||
void ServerThread();
|
||||
public:
|
||||
HtcmiscImpl(htclow::HtclowManager *htclow_manager);
|
||||
~HtcmiscImpl();
|
||||
public:
|
||||
void Cancel();
|
||||
/* TODO */
|
||||
};
|
||||
|
||||
|
|
75
libraries/libstratosphere/source/htc/server/htc_observer.cpp
Normal file
75
libraries/libstratosphere/source/htc/server/htc_observer.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "htc_observer.hpp"
|
||||
|
||||
namespace ams::htc::server {
|
||||
|
||||
Observer::Observer(const HtcmiscImpl &misc_impl)
|
||||
: m_connect_event(os::EventClearMode_ManualClear, true),
|
||||
m_disconnect_event(os::EventClearMode_ManualClear, true),
|
||||
m_stop_event(os::EventClearMode_ManualClear),
|
||||
m_misc_impl(misc_impl),
|
||||
m_thread_running(false),
|
||||
m_stopped(false),
|
||||
m_connected(false),
|
||||
m_is_service_available(false)
|
||||
{
|
||||
/* Initialize htcs library. */
|
||||
AMS_ABORT("htcs::impl::HtcsManagerHolder::AddReference();");
|
||||
|
||||
/* Update our event state. */
|
||||
this->UpdateEvent();
|
||||
|
||||
/* Start. */
|
||||
R_ABORT_UNLESS(this->Start());
|
||||
}
|
||||
|
||||
Result Observer::Start() {
|
||||
/* Check that we're not already running. */
|
||||
AMS_ASSERT(!m_thread_running);
|
||||
|
||||
/* Create the thread. */
|
||||
R_TRY(os::CreateThread(std::addressof(m_observer_thread), ObserverThreadEntry, this, m_observer_thread_stack, sizeof(m_observer_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(htc, HtcObserver)));
|
||||
|
||||
/* Set the thread name pointer. */
|
||||
os::SetThreadNamePointer(std::addressof(m_observer_thread), AMS_GET_SYSTEM_THREAD_NAME(htc, HtcObserver));
|
||||
|
||||
/* Mark our thread as running. */
|
||||
m_thread_running = true;
|
||||
m_stopped = false;
|
||||
|
||||
/* Start our thread. */
|
||||
os::StartThread(std::addressof(m_observer_thread));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void Observer::UpdateEvent() {
|
||||
if (m_connected && m_is_service_available) {
|
||||
m_disconnect_event.Clear();
|
||||
m_connect_event.Signal();
|
||||
} else {
|
||||
m_connect_event.Clear();
|
||||
m_disconnect_event.Signal();
|
||||
}
|
||||
}
|
||||
|
||||
void Observer::ObserverThreadBody() {
|
||||
AMS_ABORT("Observer::ObserverThreadBody");
|
||||
}
|
||||
|
||||
}
|
|
@ -23,15 +23,24 @@ namespace ams::htc::server {
|
|||
private:
|
||||
os::SystemEvent m_connect_event;
|
||||
os::SystemEvent m_disconnect_event;
|
||||
os::Event m_event_60;
|
||||
os::Event m_stop_event;
|
||||
os::ThreadType m_observer_thread;
|
||||
const HtcmiscImpl &m_misc_impl;
|
||||
bool m_thread_running;
|
||||
bool m_stopped;
|
||||
bool m_connected;
|
||||
bool m_is_service_available;
|
||||
alignas(os::ThreadStackAlignment) u8 m_observer_thread_stack[os::MemoryPageSize];
|
||||
public:
|
||||
Observer(const HtcmiscImpl &misc_impl);
|
||||
private:
|
||||
static void ObserverThreadEntry(void *arg) { static_cast<Observer *>(arg)->ObserverThreadBody(); }
|
||||
|
||||
void ObserverThreadBody();
|
||||
private:
|
||||
Result Start();
|
||||
|
||||
void UpdateEvent();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "htc_htcmisc_rpc_server.hpp"
|
||||
|
||||
namespace ams::htc::server::rpc {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline size_t ReceiveThreadStackSize = os::MemoryPageSize;
|
||||
|
||||
alignas(os::ThreadStackAlignment) constinit u8 g_receive_thread_stack[ReceiveThreadStackSize];
|
||||
|
||||
}
|
||||
|
||||
HtcmiscRpcServer::HtcmiscRpcServer(driver::IDriver *driver, htclow::ChannelId channel)
|
||||
: m_00(0),
|
||||
m_driver(driver),
|
||||
m_channel_id(channel),
|
||||
m_receive_thread_stack(g_receive_thread_stack),
|
||||
m_cancelled(false),
|
||||
m_thread_running(false)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "htc_rpc_client.hpp"
|
||||
|
||||
namespace ams::htc::server::rpc {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline size_t ThreadStackSize = os::MemoryPageSize;
|
||||
|
||||
alignas(os::ThreadStackAlignment) constinit u8 g_receive_thread_stack[ThreadStackSize];
|
||||
alignas(os::ThreadStackAlignment) constinit u8 g_send_thread_stack[ThreadStackSize];
|
||||
|
||||
constinit os::SdkMutex g_rpc_mutex;
|
||||
|
||||
}
|
||||
|
||||
RpcClient::RpcClient(driver::IDriver *driver, htclow::ChannelId channel)
|
||||
: m_00(0),
|
||||
m_driver(driver),
|
||||
m_channel_id(channel),
|
||||
m_receive_thread_stack(g_receive_thread_stack),
|
||||
m_send_thread_stack(g_send_thread_stack),
|
||||
m_mutex(g_rpc_mutex),
|
||||
m_cancelled(false),
|
||||
m_thread_running(false)
|
||||
{
|
||||
/* Initialize all events. */
|
||||
/* TODO: MaxTaskCount? */
|
||||
for (size_t i = 0; i < util::size(m_5F8_events); ++i) {
|
||||
os::InitializeEvent(std::addressof(m_5F8_events[i]), false, os::EventClearMode_AutoClear);
|
||||
os::InitializeEvent(std::addressof(m_1138_events[i]), false, os::EventClearMode_AutoClear);
|
||||
}
|
||||
|
||||
/* TODO: Clear all of m_3C0 array to zero. */
|
||||
}
|
||||
|
||||
}
|
|
@ -28,7 +28,7 @@ namespace ams::htc::server::rpc {
|
|||
void *m_send_thread_stack;
|
||||
os::ThreadType m_receive_thread;
|
||||
os::ThreadType m_send_thread;
|
||||
os::SdkMutex *m_p_mutex;
|
||||
os::SdkMutex &m_mutex;
|
||||
/* TODO: m_task_id_free_list */
|
||||
/* TODO: m_task_table */
|
||||
/* TODO: m_3C0[0x48] */
|
||||
|
|
|
@ -351,6 +351,22 @@ namespace ams::htclow::ctrl {
|
|||
this->DisconnectInternal();
|
||||
}
|
||||
|
||||
void HtcctrlService::DisconnectInternal() {
|
||||
/* Disconnect, if we need to. */
|
||||
if (m_state_machine->IsDisconnectionNeeded()) {
|
||||
/* Send a disconnect packet. */
|
||||
m_send_buffer.AddPacket(m_packet_factory->MakeDisconnectPacket());
|
||||
|
||||
/* Signal our event. */
|
||||
m_event.Signal();
|
||||
|
||||
/* Wait for us to be disconnected. */
|
||||
while (!m_state_machine->IsDisconnected()) {
|
||||
m_condvar.Wait(m_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HtcctrlService::Resume() {
|
||||
/* Lock ourselves. */
|
||||
std::scoped_lock lk(m_mutex);
|
||||
|
|
|
@ -64,6 +64,13 @@ namespace ams::htclow::ctrl {
|
|||
return !ctrl::IsDisconnected(m_state) && m_state != HtcctrlState_DriverConnected;
|
||||
}
|
||||
|
||||
bool HtcctrlStateMachine::IsDisconnectionNeeded() {
|
||||
/* Lock ourselves. */
|
||||
std::scoped_lock lk(m_mutex);
|
||||
|
||||
return !ctrl::IsDisconnected(m_state) && m_state != HtcctrlState_Sleep && m_state != HtcctrlState_DriverConnected;
|
||||
}
|
||||
|
||||
bool HtcctrlStateMachine::IsConnected() {
|
||||
/* Lock ourselves. */
|
||||
std::scoped_lock lk(m_mutex);
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace ams::htclow::ctrl {
|
|||
bool IsSleepingStatusChanged();
|
||||
|
||||
bool IsInformationNeeded();
|
||||
bool IsDisconnectionNeeded();
|
||||
|
||||
bool IsConnected();
|
||||
bool IsReadied();
|
||||
|
|
|
@ -16,9 +16,17 @@
|
|||
#include <stratosphere.hpp>
|
||||
#include "htclow_mux_channel_impl.hpp"
|
||||
#include "../htclow_packet_factory.hpp"
|
||||
#include "../htclow_default_channel_config.hpp"
|
||||
|
||||
namespace ams::htclow::mux {
|
||||
|
||||
SendBuffer::SendBuffer(impl::ChannelInternalType channel, PacketFactory *pf)
|
||||
: m_channel(channel), m_packet_factory(pf), m_ring_buffer(), m_packet_list(),
|
||||
m_version(ProtocolVersion), m_flow_control_enabled(true), m_max_packet_size(DefaultChannelConfig.max_packet_size)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
SendBuffer::~SendBuffer() {
|
||||
m_ring_buffer.Clear();
|
||||
this->Clear();
|
||||
|
|
Loading…
Reference in a new issue