Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic support for 19.0.0 #651

Merged
merged 9 commits into from
Nov 24, 2024
11 changes: 7 additions & 4 deletions nx/include/switch/kernel/svc.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ typedef enum {
InfoType_IoRegionHint = 27, ///< [16.0.0+] Low bits of the physical address for a KIoRegion.
InfoType_AliasRegionExtraSize = 28, ///< [18.0.0+] Extra size added to the reserved region.

InfoType_TransferMemoryHint = 34, ///< [19.0.0+] Low bits of the process address for a KTransferMemory.

InfoType_ThreadTickCountDeprecated = 0xF0000002, ///< [1.0.0-12.1.0] Number of ticks spent on thread.
} InfoType;

Expand Down Expand Up @@ -262,9 +264,10 @@ typedef enum {

/// WaitForAddress behaviors.
typedef enum {
ArbitrationType_WaitIfLessThan = 0, ///< Wait if the value is less than argument.
ArbitrationType_DecrementAndWaitIfLessThan = 1, ///< Decrement the value and wait if it is less than argument.
ArbitrationType_WaitIfEqual = 2, ///< Wait if the value is equal to argument.
ArbitrationType_WaitIfLessThan = 0, ///< Wait if the 32-bit value is less than argument.
ArbitrationType_DecrementAndWaitIfLessThan = 1, ///< Decrement the 32-bit value and wait if it is less than argument.
ArbitrationType_WaitIfEqual = 2, ///< Wait if the 32-bit value is equal to argument.
ArbitrationType_WaitIfEqual64 = 3, ///< [19.0.0+] Wait if the 64-bit value is equal to argument.
} ArbitrationType;

/// Context of a scheduled thread.
Expand Down Expand Up @@ -809,7 +812,7 @@ Result svcGetThreadContext3(ThreadContext* ctx, Handle thread);
* @return Result code.
* @note Syscall number 0x34.
*/
Result svcWaitForAddress(void *address, u32 arb_type, s32 value, s64 timeout);
Result svcWaitForAddress(void *address, u32 arb_type, s64 value, s64 timeout);

/**
* @brief Signals (and updates) an address depending on type and value. [4.0.0+]
Expand Down
4 changes: 3 additions & 1 deletion nx/include/switch/services/caps.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ typedef struct {
CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime
u8 storage; ///< \ref CapsAlbumStorage
u8 content; ///< \ref CapsAlbumFileContents
u8 pad_x12[0x6]; ///< padding
u8 unknown_12; ///< [19.0.0+]
u8 unknown_13; ///< [19.0.0+]
u8 pad_x14[0x4]; ///< padding
} CapsAlbumFileId;

/// AlbumEntry
Expand Down
15 changes: 11 additions & 4 deletions nx/include/switch/services/capsc.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
#include "../sf/service.h"
#include "../services/caps.h"

typedef struct {
u64 application_id;
u8 unknown_08;
u8 unknown_09;
u8 reserved[6];
} CapsApplicationId;

/// Initialize caps:c
Result capscInitialize(void);

Expand Down Expand Up @@ -40,7 +47,7 @@ Result capscNotifyAlbumStorageIsUnAvailable(CapsAlbumStorage storage);
* @param[in] appletResourceUserId AppletResourceUserId.
* @param[in] application_id ApplicationId.
*/
Result capscRegisterAppletResourceUserId(u64 appletResourceUserId, u64 application_id);
Result capscRegisterAppletResourceUserId(u64 appletResourceUserId, const CapsApplicationId *application_id);

/**
* @brief Unregister an applet.
Expand All @@ -49,7 +56,7 @@ Result capscRegisterAppletResourceUserId(u64 appletResourceUserId, u64 applicati
* @param[in] appletResourceUserId AppletResourceUserId.
* @param[in] application_id ApplicationId.
*/
Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, u64 application_id);
Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, const CapsApplicationId *application_id);

/**
* @brief Get an ApplicationId that corresponds to an AppletResourceUserId.
Expand All @@ -58,7 +65,7 @@ Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, u64 applica
* @param[out] application_id ApplicationId.
* @param[in] appletResourceUserId AppletResourceUserId.
*/
Result capscGetApplicationIdFromAruid(u64 *application_id, u64 aruid);
Result capscGetApplicationIdFromAruid(CapsApplicationId *application_id, u64 aruid);

/**
* @brief Checks whether an ApplicationId is registered.
Expand All @@ -74,7 +81,7 @@ Result capscCheckApplicationIdRegistered(u64 application_id);
* @param[in] contents \ref CapsAlbumFileContents
* @param[out] file_id \ref CapsAlbumFileId
*/
Result capscGenerateCurrentAlbumFileId(u64 application_id, CapsAlbumFileContents contents, CapsAlbumFileId *file_id);
Result capscGenerateCurrentAlbumFileId(const CapsApplicationId *application_id, CapsAlbumFileContents contents, CapsAlbumFileId *file_id);

/**
* @brief Generate an ApplicationAlbumEntry based on parameters.
Expand Down
4 changes: 3 additions & 1 deletion nx/include/switch/services/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,8 @@ Result fsGetRightsIdByPath(const char* path, FsRightsId* out_rights_id);
/// Retrieves the rights id and key generation corresponding to the content path. Only available on [3.0.0+], attr is ignored before [16.0.0].
Result fsGetRightsIdAndKeyGenerationByPath(const char* path, FsContentAttributes attr, u8* out_key_generation, FsRightsId* out_rights_id);

Result fsGetContentStorageInfoIndex(s32 *out); ///< [19.0.0+]

Result fsDisableAutoSaveDataCreation(void);

Result fsSetGlobalAccessLogMode(u32 mode);
Expand Down Expand Up @@ -683,7 +685,7 @@ Result fsDeviceOperatorIsGameCardInserted(FsDeviceOperator* d, bool* out);
Result fsDeviceOperatorGetGameCardHandle(FsDeviceOperator* d, FsGameCardHandle* out);
Result fsDeviceOperatorGetGameCardUpdatePartitionInfo(FsDeviceOperator* d, const FsGameCardHandle* handle, FsGameCardUpdatePartitionInfo* out);
Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCardHandle* handle, u8 *out);
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64 size);
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64* out_size, s64 size);
Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size);
Result fsDeviceOperatorGetGameCardErrorReportInfo(FsDeviceOperator* d, FsGameCardErrorReportInfo* out);
Result fsDeviceOperatorGetGameCardDeviceId(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size);
Expand Down
17 changes: 16 additions & 1 deletion nx/include/switch/services/ldr.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ typedef struct {
u32 acid_fac_size;
u32 aci0_fah_size;
u8 ac_buffer[0x3E0];
} LoaderProgramInfoV1;

typedef struct {
u8 main_thread_priority;
u8 default_cpu_id;
u16 application_type;
u32 main_thread_stack_size;
u64 program_id;
u32 acid_sac_size;
u32 aci0_sac_size;
u32 acid_fac_size;
u32 aci0_fah_size;
u8 unused_20[0x10];
u8 ac_buffer[0x3E0];
} LoaderProgramInfo;

typedef struct {
Expand Down Expand Up @@ -63,7 +77,8 @@ Result ldrDmntFlushArguments(void);
Result ldrDmntGetProcessModuleInfo(u64 pid, LoaderModuleInfo *out_module_infos, size_t max_out_modules, s32 *num_out);

Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, Handle *out_process_h);
Result ldrPmGetProgramInfo(const NcmProgramLocation *loc, LoaderProgramInfo *out_program_info);
Result ldrPmGetProgramInfo(const NcmProgramLocation *loc, LoaderProgramInfo *out_program_info); ///< [19.0.0+/Atmosphere]
Result ldrPmGetProgramInfoV1(const NcmProgramLocation *loc, LoaderProgramInfoV1 *out_program_info); ///< [1.0.0-18.1.0/Non-Atmosphere]
Result ldrPmPinProgram(const NcmProgramLocation *loc, u64 *out_pin_id);
Result ldrPmUnpinProgram(u64 pin_id);
Result ldrPmSetEnabledProgramVerification(bool enabled); ///< [10.0.0+]
26 changes: 15 additions & 11 deletions nx/source/services/capsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,30 +54,34 @@ Result capscNotifyAlbumStorageIsUnAvailable(CapsAlbumStorage storage) {
return _capscCmdInU8NoOut(&g_capscSrv, 2002, storage);
}

Result capscRegisterAppletResourceUserId(u64 appletResourceUserId, u64 application_id) {
Result capscRegisterAppletResourceUserId(u64 appletResourceUserId, const CapsApplicationId *application_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u64 appletResourceUserId;
u64 applicationId;
} in = { appletResourceUserId, application_id };
CapsApplicationId applicationId;
} in = { appletResourceUserId, *application_id };
return serviceDispatchIn(&g_capscSrv, 2011, in);
}

Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, u64 application_id) {
Result capscUnregisterAppletResourceUserId(u64 appletResourceUserId, const CapsApplicationId *application_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u64 appletResourceUserId;
u64 applicationId;
} in = { appletResourceUserId, application_id };
CapsApplicationId applicationId;
} in = { appletResourceUserId, *application_id };
return serviceDispatchIn(&g_capscSrv, 2012, in);
}

Result capscGetApplicationIdFromAruid(u64 *application_id, u64 aruid) {
Result capscGetApplicationIdFromAruid(CapsApplicationId *application_id, u64 aruid) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return serviceDispatchInOut(&g_capscSrv, 2013, aruid, *application_id);

if (hosversionAtLeast(19,0,0))
return serviceDispatchInOut(&g_capscSrv, 2013, aruid, *application_id);
else
return serviceDispatchInOut(&g_capscSrv, 2013, aruid, application_id->application_id);
}

Result capscCheckApplicationIdRegistered(u64 application_id) {
Expand All @@ -86,13 +90,13 @@ Result capscCheckApplicationIdRegistered(u64 application_id) {
return serviceDispatchIn(&g_capscSrv, 2014, application_id);
}

Result capscGenerateCurrentAlbumFileId(u64 application_id, CapsAlbumFileContents contents, CapsAlbumFileId *file_id) {
Result capscGenerateCurrentAlbumFileId(const CapsApplicationId *application_id, CapsAlbumFileContents contents, CapsAlbumFileId *file_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u8 type;
u64 applicationId;
} in = { contents, application_id };
CapsApplicationId applicationId;
} in = { contents, *application_id };
return serviceDispatchInOut(&g_capscSrv, 2101, in, *file_id);
}

Expand Down
26 changes: 24 additions & 2 deletions nx/source/services/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,13 @@ Result fsGetAndClearErrorInfo(FsFileSystemProxyErrorInfo *out) {
return _fsObjectDispatchOut(&g_fsSrv, 800, *out);
}

Result fsGetContentStorageInfoIndex(s32 *out) {
if (hosversionBefore(19,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

return _fsCmdNoInOutU32(&g_fsSrv, (u32 *)out, 820);
}

Result fsDisableAutoSaveDataCreation(void) {
return _fsCmdNoIO(&g_fsSrv, 1003);
}
Expand Down Expand Up @@ -1233,15 +1240,30 @@ Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCar
return _fsObjectDispatchInOut(&d->s, 205, *handle, *out);
}

Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64 size) {
Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64* out_size, s64 size) {
const struct {
FsGameCardHandle handle;
s64 buffer_size;
} in = { *handle, size };

return _fsObjectDispatchIn(&d->s, 206, in,
// Assume old gamecard certificate size on pre-19.0.0
s64 os = 0x200;
Result rc;

if (hosversionAtLeast(19,0,0)) {
rc = _fsObjectDispatchInOut(&d->s, 206, in, os,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { dst, dst_size } });
} else {
rc = _fsObjectDispatchIn(&d->s, 206, in,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { dst, dst_size } });
}

if (R_SUCCEEDED(rc))
*out_size = os;

return rc;
}

Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size) {
Expand Down
13 changes: 13 additions & 0 deletions nx/source/services/ldr.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,19 @@ Result ldrPmCreateProcess(u64 pin_id, u32 flags, Handle reslimit_h, Handle *out_
}

Result ldrPmGetProgramInfo(const NcmProgramLocation *loc, LoaderProgramInfo *out_program_info) {
if (!hosversionIsAtmosphere() && hosversionBefore(19, 0, 0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

return serviceDispatchIn(&g_ldrPmSrv, 1, *loc,
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { out_program_info, sizeof(*out_program_info) } },
);
}

Result ldrPmGetProgramInfoV1(const NcmProgramLocation *loc, LoaderProgramInfoV1 *out_program_info) {
if (hosversionIsAtmosphere() || hosversionAtLeast(19,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);

return serviceDispatchIn(&g_ldrPmSrv, 1, *loc,
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
.buffers = { { out_program_info, sizeof(*out_program_info) } },
Expand Down
4 changes: 2 additions & 2 deletions nx/switch.ld
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,11 @@ SECTIONS
PROVIDE_HIDDEN( __bss_start__ = ADDR(.bss) );
PROVIDE_HIDDEN( __bss_end__ = __tls_end );

PROVIDE_HIDDEN( __end__ = ABSOLUTE(.) );
PROVIDE_HIDDEN( __end__ = . );

/* =========== Argument buffer =========== */
. = ALIGN(0x1000);
PROVIDE_HIDDEN( __argdata__ = ABSOLUTE(.) );
PROVIDE_HIDDEN( __argdata__ = . );

/* ==================
==== Metadata ====
Expand Down
Loading