mirror of
https://github.com/citra-emu/citra-canary.git
synced 2024-12-23 20:25:37 +00:00
Merge pull request #279 from yuriks/session
Remove SyncRequest from K::Object and create a new K::Session type
This commit is contained in:
commit
d0ce9d58f6
|
@ -108,6 +108,7 @@ set(HEADERS
|
|||
hle/kernel/kernel.h
|
||||
hle/kernel/mutex.h
|
||||
hle/kernel/semaphore.h
|
||||
hle/kernel/session.h
|
||||
hle/kernel/shared_memory.h
|
||||
hle/kernel/thread.h
|
||||
hle/service/ac_u.h
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/file_util.h"
|
||||
#include "common/math_util.h"
|
||||
|
@ -10,8 +12,8 @@
|
|||
#include "core/file_sys/archive_sdmc.h"
|
||||
#include "core/file_sys/directory.h"
|
||||
#include "core/hle/kernel/archive.h"
|
||||
#include "core/hle/kernel/session.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Kernel namespace
|
||||
|
@ -41,19 +43,15 @@ enum class DirectoryCommand : u32 {
|
|||
Close = 0x08020000,
|
||||
};
|
||||
|
||||
class Archive : public Object {
|
||||
class Archive : public Kernel::Session {
|
||||
public:
|
||||
std::string GetTypeName() const override { return "Archive"; }
|
||||
std::string GetName() const override { return name; }
|
||||
|
||||
static Kernel::HandleType GetStaticHandleType() { return HandleType::Archive; }
|
||||
Kernel::HandleType GetHandleType() const override { return HandleType::Archive; }
|
||||
std::string GetName() const override { return "Archive: " + name; }
|
||||
|
||||
std::string name; ///< Name of archive (optional)
|
||||
FileSys::Archive* backend; ///< Archive backend interface
|
||||
|
||||
ResultVal<bool> SyncRequest() override {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]);
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -102,7 +100,8 @@ public:
|
|||
default:
|
||||
{
|
||||
LOG_ERROR(Service_FS, "Unknown command=0x%08X", cmd);
|
||||
return UnimplementedFunction(ErrorModule::FS);
|
||||
cmd_buff[0] = UnimplementedFunction(ErrorModule::FS).raw;
|
||||
return MakeResult<bool>(false);
|
||||
}
|
||||
}
|
||||
cmd_buff[1] = 0; // No error
|
||||
|
@ -110,19 +109,15 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class File : public Object {
|
||||
class File : public Kernel::Session {
|
||||
public:
|
||||
std::string GetTypeName() const override { return "File"; }
|
||||
std::string GetName() const override { return path.DebugStr(); }
|
||||
|
||||
static Kernel::HandleType GetStaticHandleType() { return HandleType::File; }
|
||||
Kernel::HandleType GetHandleType() const override { return HandleType::File; }
|
||||
std::string GetName() const override { return "Path: " + path.DebugStr(); }
|
||||
|
||||
FileSys::Path path; ///< Path of the file
|
||||
std::unique_ptr<FileSys::File> backend; ///< File backend interface
|
||||
|
||||
ResultVal<bool> SyncRequest() override {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]);
|
||||
switch (cmd) {
|
||||
|
||||
|
@ -188,19 +183,15 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class Directory : public Object {
|
||||
class Directory : public Kernel::Session {
|
||||
public:
|
||||
std::string GetTypeName() const override { return "Directory"; }
|
||||
std::string GetName() const override { return path.DebugStr(); }
|
||||
|
||||
static Kernel::HandleType GetStaticHandleType() { return HandleType::Directory; }
|
||||
Kernel::HandleType GetHandleType() const override { return HandleType::Directory; }
|
||||
std::string GetName() const override { return "Directory: " + path.DebugStr(); }
|
||||
|
||||
FileSys::Path path; ///< Path of the directory
|
||||
std::unique_ptr<FileSys::Directory> backend; ///< File backend interface
|
||||
|
||||
ResultVal<bool> SyncRequest() override {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]);
|
||||
switch (cmd) {
|
||||
|
||||
|
@ -230,7 +221,7 @@ public:
|
|||
LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
|
||||
ResultCode error = UnimplementedFunction(ErrorModule::FS);
|
||||
cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that.
|
||||
return error;
|
||||
return MakeResult<bool>(false);
|
||||
}
|
||||
cmd_buff[1] = 0; // No error
|
||||
return MakeResult<bool>(false);
|
||||
|
|
|
@ -22,7 +22,7 @@ enum KernelHandle {
|
|||
enum class HandleType : u32 {
|
||||
Unknown = 0,
|
||||
Port = 1,
|
||||
Service = 2,
|
||||
Session = 2,
|
||||
Event = 3,
|
||||
Mutex = 4,
|
||||
SharedMemory = 5,
|
||||
|
@ -30,10 +30,7 @@ enum class HandleType : u32 {
|
|||
Thread = 7,
|
||||
Process = 8,
|
||||
AddressArbiter = 9,
|
||||
File = 10,
|
||||
Semaphore = 11,
|
||||
Archive = 12,
|
||||
Directory = 13,
|
||||
Semaphore = 10,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -52,15 +49,6 @@ public:
|
|||
virtual std::string GetName() const { return "[UNKNOWN KERNEL OBJECT]"; }
|
||||
virtual Kernel::HandleType GetHandleType() const = 0;
|
||||
|
||||
/**
|
||||
* Synchronize kernel object.
|
||||
* @return True if the current thread should wait as a result of the sync
|
||||
*/
|
||||
virtual ResultVal<bool> SyncRequest() {
|
||||
LOG_ERROR(Kernel, "(UNIMPLEMENTED)");
|
||||
return UnimplementedFunction(ErrorModule::Kernel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for kernel object to synchronize.
|
||||
* @return True if the current thread should wait as a result of the wait
|
||||
|
|
58
src/core/hle/kernel/session.h
Normal file
58
src/core/hle/kernel/session.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright 2014 Citra Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header
|
||||
|
||||
/**
|
||||
* Returns a pointer to the command buffer in kernel memory
|
||||
* @param offset Optional offset into command buffer
|
||||
* @return Pointer to command buffer
|
||||
*/
|
||||
inline static u32* GetCommandBuffer(const int offset=0) {
|
||||
return (u32*)Memory::GetPointer(Memory::KERNEL_MEMORY_VADDR + kCommandHeaderOffset + offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kernel object representing the client endpoint of an IPC session. Sessions are the basic CTR-OS
|
||||
* primitive for communication between different processes, and are used to implement service calls
|
||||
* to the various system services.
|
||||
*
|
||||
* To make a service call, the client must write the command header and parameters to the buffer
|
||||
* located at offset 0x80 of the TLS (Thread-Local Storage) area, then execute a SendSyncRequest
|
||||
* SVC call with its Session handle. The kernel will read the command header, using it to marshall
|
||||
* the parameters to the process at the server endpoint of the session. After the server replies to
|
||||
* the request, the response is marshalled back to the caller's TLS buffer and control is
|
||||
* transferred back to it.
|
||||
*
|
||||
* In Citra, only the client endpoint is currently implemented and only HLE calls, where the IPC
|
||||
* request is answered by C++ code in the emulator, are supported. When SendSyncRequest is called
|
||||
* with the session handle, this class's SyncRequest method is called, which should read the TLS
|
||||
* buffer and emulate the call accordingly. Since the code can directly read the emulated memory,
|
||||
* no parameter marshalling is done.
|
||||
*
|
||||
* In the long term, this should be turned into the full-fledged IPC mechanism implemented by
|
||||
* CTR-OS so that IPC calls can be optionally handled by the real implementations of processes, as
|
||||
* opposed to HLE simulations.
|
||||
*/
|
||||
class Session : public Object {
|
||||
public:
|
||||
std::string GetTypeName() const override { return "Session"; }
|
||||
|
||||
static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Session; }
|
||||
Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Session; }
|
||||
|
||||
/**
|
||||
* Handles a synchronous call to this session using HLE emulation. Emulated <-> emulated calls
|
||||
* aren't supported yet.
|
||||
*/
|
||||
virtual ResultVal<bool> SyncRequest() = 0;
|
||||
};
|
||||
|
||||
}
|
|
@ -18,7 +18,7 @@ namespace AC_U {
|
|||
* 2 : Output connection type, 0 = none, 1 = Old3DS Internet, 2 = New3DS Internet.
|
||||
*/
|
||||
void GetWifiStatus(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(purpasmart96): This function is only a stub,
|
||||
// it returns a valid result without implementing full functionality.
|
||||
|
|
|
@ -40,7 +40,7 @@ enum class SignalType : u32 {
|
|||
};
|
||||
|
||||
void Initialize(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
cmd_buff[3] = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Menu"); // APT menu event handle
|
||||
cmd_buff[4] = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Pause"); // APT pause event handle
|
||||
|
@ -57,7 +57,7 @@ void Initialize(Service::Interface* self) {
|
|||
}
|
||||
|
||||
void GetLockHandle(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
|
||||
|
||||
if (0 == lock_handle) {
|
||||
|
@ -78,14 +78,14 @@ void GetLockHandle(Service::Interface* self) {
|
|||
}
|
||||
|
||||
void Enable(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
u32 unk = cmd_buff[1]; // TODO(bunnei): What is this field used for?
|
||||
cmd_buff[1] = 0; // No error
|
||||
LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
|
||||
}
|
||||
|
||||
void InquireNotification(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
u32 app_id = cmd_buff[2];
|
||||
cmd_buff[1] = 0; // No error
|
||||
cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type
|
||||
|
@ -112,7 +112,7 @@ void InquireNotification(Service::Interface* self) {
|
|||
* 8 : Output parameter buffer ptr
|
||||
*/
|
||||
void ReceiveParameter(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
u32 app_id = cmd_buff[1];
|
||||
u32 buffer_size = cmd_buff[2];
|
||||
cmd_buff[1] = 0; // No error
|
||||
|
@ -143,7 +143,7 @@ void ReceiveParameter(Service::Interface* self) {
|
|||
* 8 : Output parameter buffer ptr
|
||||
*/
|
||||
void GlanceParameter(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
u32 app_id = cmd_buff[1];
|
||||
u32 buffer_size = cmd_buff[2];
|
||||
|
||||
|
@ -170,7 +170,7 @@ void GlanceParameter(Service::Interface* self) {
|
|||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void AppletUtility(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// These are from 3dbrew - I'm not really sure what they're used for.
|
||||
u32 unk = cmd_buff[1];
|
||||
|
@ -196,7 +196,7 @@ void AppletUtility(Service::Interface* self) {
|
|||
void GetSharedFont(Service::Interface* self) {
|
||||
LOG_TRACE(Kernel_SVC, "called");
|
||||
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
if (!shared_font.empty()) {
|
||||
// TODO(bunnei): This function shouldn't copy the shared font every time it's called.
|
||||
|
|
|
@ -52,7 +52,7 @@ static const std::array<u16, 187> country_codes = {
|
|||
* 2 : Country's 2-char string
|
||||
*/
|
||||
static void GetCountryCodeString(Service::Interface* self) {
|
||||
u32* cmd_buffer = Service::GetCommandBuffer();
|
||||
u32* cmd_buffer = Kernel::GetCommandBuffer();
|
||||
u32 country_code_id = cmd_buffer[1];
|
||||
|
||||
if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) {
|
||||
|
@ -74,7 +74,7 @@ static void GetCountryCodeString(Service::Interface* self) {
|
|||
* 2 : Country Code ID
|
||||
*/
|
||||
static void GetCountryCodeID(Service::Interface* self) {
|
||||
u32* cmd_buffer = Service::GetCommandBuffer();
|
||||
u32* cmd_buffer = Kernel::GetCommandBuffer();
|
||||
u16 country_code = cmd_buffer[1];
|
||||
u16 country_code_id = 0;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ static Handle interrupt_event;
|
|||
* 2 : (inaddr << 1) + 0x1FF40000 (where 0x1FF00000 is the DSP RAM address)
|
||||
*/
|
||||
void ConvertProcessAddressFromDspDram(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
u32 addr = cmd_buff[1];
|
||||
|
||||
|
@ -48,7 +48,7 @@ void ConvertProcessAddressFromDspDram(Service::Interface* self) {
|
|||
* 2 : Component loaded, 0 on not loaded, 1 on loaded
|
||||
*/
|
||||
void LoadComponent(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
cmd_buff[1] = 0; // No error
|
||||
cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware
|
||||
|
@ -65,7 +65,7 @@ void LoadComponent(Service::Interface* self) {
|
|||
* 3 : Semaphore event handle
|
||||
*/
|
||||
void GetSemaphoreEventHandle(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
cmd_buff[1] = 0; // No error
|
||||
cmd_buff[3] = semaphore_event; // Event handle
|
||||
|
@ -83,7 +83,7 @@ void GetSemaphoreEventHandle(Service::Interface* self) {
|
|||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void RegisterInterruptEvents(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
interrupt_event = static_cast<Handle>(cmd_buff[4]);
|
||||
|
||||
|
@ -100,7 +100,7 @@ void RegisterInterruptEvents(Service::Interface* self) {
|
|||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void WriteReg0x10(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
Kernel::SignalEvent(interrupt_event);
|
||||
|
||||
|
@ -121,7 +121,7 @@ void WriteReg0x10(Service::Interface* self) {
|
|||
* 2 : Number of bytes read from pipe
|
||||
*/
|
||||
void ReadPipeIfPossible(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
u32 size = cmd_buff[3] & 0xFFFF;// Lower 16 bits are size
|
||||
VAddr addr = cmd_buff[0x41];
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
namespace FS_User {
|
||||
|
||||
static void Initialize(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(Link Mauve): check the behavior when cmd_buff[1] isn't 32, as per
|
||||
// http://3dbrew.org/wiki/FS:Initialize#Request
|
||||
|
@ -43,7 +43,7 @@ static void Initialize(Service::Interface* self) {
|
|||
* 3 : File handle
|
||||
*/
|
||||
static void OpenFile(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
|
||||
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
|
||||
|
@ -86,7 +86,7 @@ static void OpenFile(Service::Interface* self) {
|
|||
* 3 : File handle
|
||||
*/
|
||||
static void OpenFileDirectly(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
auto archive_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[2]);
|
||||
auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[3]);
|
||||
|
@ -141,7 +141,7 @@ static void OpenFileDirectly(Service::Interface* self) {
|
|||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void DeleteFile(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
|
||||
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
|
||||
|
@ -175,7 +175,7 @@ void DeleteFile(Service::Interface* self) {
|
|||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void RenameFile(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to
|
||||
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
|
||||
|
@ -210,7 +210,7 @@ void RenameFile(Service::Interface* self) {
|
|||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void DeleteDirectory(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
|
||||
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
|
||||
|
@ -239,7 +239,7 @@ void DeleteDirectory(Service::Interface* self) {
|
|||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
static void CreateDirectory(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO: cmd_buff[2], aka archive handle lower word, isn't used according to
|
||||
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
|
||||
|
@ -272,7 +272,7 @@ static void CreateDirectory(Service::Interface* self) {
|
|||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void RenameDirectory(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to
|
||||
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
|
||||
|
@ -296,7 +296,7 @@ void RenameDirectory(Service::Interface* self) {
|
|||
}
|
||||
|
||||
static void OpenDirectory(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
|
||||
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
|
||||
|
@ -332,7 +332,7 @@ static void OpenDirectory(Service::Interface* self) {
|
|||
* 3 : Archive handle upper word (same as file handle)
|
||||
*/
|
||||
static void OpenArchive(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
auto archive_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[1]);
|
||||
auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[2]);
|
||||
|
@ -365,7 +365,7 @@ static void OpenArchive(Service::Interface* self) {
|
|||
* 2 : Whether the Sdmc could be detected
|
||||
*/
|
||||
static void IsSdmcDetected(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
cmd_buff[1] = 0;
|
||||
cmd_buff[2] = Settings::values.use_virtual_sd ? 1 : 0;
|
||||
|
|
|
@ -72,7 +72,7 @@ static void WriteHWRegs(u32 base_address, u32 size_in_bytes, const u32* data) {
|
|||
|
||||
/// Write a GSP GPU hardware register
|
||||
static void WriteHWRegs(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
u32 reg_addr = cmd_buff[1];
|
||||
u32 size = cmd_buff[2];
|
||||
|
||||
|
@ -83,7 +83,7 @@ static void WriteHWRegs(Service::Interface* self) {
|
|||
|
||||
/// Read a GSP GPU hardware register
|
||||
static void ReadHWRegs(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
u32 reg_addr = cmd_buff[1];
|
||||
u32 size = cmd_buff[2];
|
||||
|
||||
|
@ -136,7 +136,7 @@ static void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
|
|||
* 1: Result code
|
||||
*/
|
||||
static void SetBufferSwap(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
u32 screen_id = cmd_buff[1];
|
||||
FrameBufferInfo* fb_info = (FrameBufferInfo*)&cmd_buff[2];
|
||||
SetBufferSwap(screen_id, *fb_info);
|
||||
|
@ -155,7 +155,7 @@ static void SetBufferSwap(Service::Interface* self) {
|
|||
* 4 : Handle to GSP shared memory
|
||||
*/
|
||||
static void RegisterInterruptRelayQueue(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
u32 flags = cmd_buff[1];
|
||||
g_interrupt_event = cmd_buff[3];
|
||||
g_shared_memory = Kernel::CreateSharedMemory("GSPSharedMem");
|
||||
|
@ -323,7 +323,7 @@ static void TriggerCmdReqQueue(Service::Interface* self) {
|
|||
}
|
||||
}
|
||||
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
cmd_buff[1] = 0; // No error
|
||||
}
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ void PadUpdateComplete() {
|
|||
* 8 : Event signaled by HID_User
|
||||
*/
|
||||
static void GetIPCHandles(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
cmd_buff[1] = 0; // No error
|
||||
cmd_buff[3] = shared_mem;
|
||||
|
|
|
@ -34,7 +34,7 @@ static bool battery_is_charging = true;
|
|||
* 2 : Output of function, 0 = not charging, 1 = charging.
|
||||
*/
|
||||
static void GetAdapterState(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(purpasmart96): This function is only a stub,
|
||||
// it returns a valid result without implementing full functionality.
|
||||
|
@ -52,7 +52,7 @@ static void GetAdapterState(Service::Interface* self) {
|
|||
* 2 : Whether the 3DS's physical shell casing is open (1) or closed (0)
|
||||
*/
|
||||
static void GetShellState(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
cmd_buff[1] = 0;
|
||||
cmd_buff[2] = shell_open ? 1 : 0;
|
||||
|
@ -68,7 +68,7 @@ static void GetShellState(Service::Interface* self) {
|
|||
* 3 = half full battery, 2 = low battery, 1 = critical battery.
|
||||
*/
|
||||
static void GetBatteryLevel(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(purpasmart96): This function is only a stub,
|
||||
// it returns a valid result without implementing full functionality.
|
||||
|
@ -86,7 +86,7 @@ static void GetBatteryLevel(Service::Interface* self) {
|
|||
* 2 : Output of function, 0 = not charging, 1 = charging.
|
||||
*/
|
||||
static void GetBatteryChargeState(Service::Interface* self) {
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(purpasmart96): This function is only a stub,
|
||||
// it returns a valid result without implementing full functionality.
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "core/mem_map.h"
|
||||
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/session.h"
|
||||
#include "core/hle/svc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -21,30 +22,19 @@
|
|||
|
||||
namespace Service {
|
||||
|
||||
static const int kMaxPortSize = 0x08; ///< Maximum size of a port name (8 characters)
|
||||
static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header
|
||||
|
||||
/**
|
||||
* Returns a pointer to the command buffer in kernel memory
|
||||
* @param offset Optional offset into command buffer
|
||||
* @return Pointer to command buffer
|
||||
*/
|
||||
inline static u32* GetCommandBuffer(const int offset=0) {
|
||||
return (u32*)Memory::GetPointer(Memory::KERNEL_MEMORY_VADDR + kCommandHeaderOffset + offset);
|
||||
}
|
||||
static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters)
|
||||
|
||||
class Manager;
|
||||
|
||||
/// Interface to a CTROS service
|
||||
class Interface : public Kernel::Object {
|
||||
class Interface : public Kernel::Session {
|
||||
// TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be
|
||||
// just something that encapsulates a session and acts as a helper to implement service
|
||||
// processes.
|
||||
|
||||
friend class Manager;
|
||||
public:
|
||||
|
||||
std::string GetName() const override { return GetPortName(); }
|
||||
std::string GetTypeName() const override { return GetPortName(); }
|
||||
|
||||
static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Service; }
|
||||
Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Service; }
|
||||
|
||||
typedef void (*Function)(Interface*);
|
||||
|
||||
|
@ -77,7 +67,7 @@ public:
|
|||
}
|
||||
|
||||
ResultVal<bool> SyncRequest() override {
|
||||
u32* cmd_buff = GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
auto itr = m_functions.find(cmd_buff[0]);
|
||||
|
||||
if (itr == m_functions.end() || itr->second.func == nullptr) {
|
||||
|
|
|
@ -16,7 +16,7 @@ static Handle g_event_handle = 0;
|
|||
static void Initialize(Service::Interface* self) {
|
||||
LOG_DEBUG(Service_SRV, "called");
|
||||
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
cmd_buff[1] = 0; // No error
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ static void Initialize(Service::Interface* self) {
|
|||
static void GetProcSemaphore(Service::Interface* self) {
|
||||
LOG_TRACE(Service_SRV, "called");
|
||||
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
// TODO(bunnei): Change to a semaphore once these have been implemented
|
||||
g_event_handle = Kernel::CreateEvent(RESETTYPE_ONESHOT, "SRV:Event");
|
||||
|
@ -36,7 +36,7 @@ static void GetProcSemaphore(Service::Interface* self) {
|
|||
|
||||
static void GetServiceHandle(Service::Interface* self) {
|
||||
ResultCode res = RESULT_SUCCESS;
|
||||
u32* cmd_buff = Service::GetCommandBuffer();
|
||||
u32* cmd_buff = Kernel::GetCommandBuffer();
|
||||
|
||||
std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize);
|
||||
Service::Interface* service = Service::g_manager->FetchFromPortName(port_name);
|
||||
|
|
|
@ -88,17 +88,14 @@ static Result ConnectToPort(Handle* out, const char* port_name) {
|
|||
|
||||
/// Synchronize to an OS service
|
||||
static Result SendSyncRequest(Handle handle) {
|
||||
// TODO(yuriks): ObjectPool::Get tries to check the Object type, which fails since this is a generic base Object,
|
||||
// so we are forced to use GetFast and manually verify the handle.
|
||||
if (!Kernel::g_object_pool.IsValid(handle)) {
|
||||
Kernel::Session* session = Kernel::g_object_pool.Get<Kernel::Session>(handle);
|
||||
if (session == nullptr) {
|
||||
return InvalidHandle(ErrorModule::Kernel).raw;
|
||||
}
|
||||
Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle);
|
||||
|
||||
_assert_msg_(KERNEL, (object != nullptr), "called, but kernel object is nullptr!");
|
||||
LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, object->GetTypeName().c_str());
|
||||
LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, session->GetName().c_str());
|
||||
|
||||
ResultVal<bool> wait = object->SyncRequest();
|
||||
ResultVal<bool> wait = session->SyncRequest();
|
||||
if (wait.Succeeded() && *wait) {
|
||||
Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct?
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue