/*
* Copyright (c) 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 .
*/
#pragma once
#include
#include
#include
#define AMS_SVC_KERN_INPUT_HANDLER(TYPE, NAME) TYPE NAME
#define AMS_SVC_KERN_OUTPUT_HANDLER(TYPE, NAME) TYPE *NAME
#define AMS_SVC_KERN_INPTR_HANDLER(TYPE, NAME) ::ams::kern::svc::KUserPointer NAME
#define AMS_SVC_KERN_OUTPTR_HANDLER(TYPE, NAME) ::ams::kern::svc::KUserPointer NAME
#define AMS_SVC_USER_INPUT_HANDLER(TYPE, NAME) TYPE NAME
#define AMS_SVC_USER_OUTPUT_HANDLER(TYPE, NAME) TYPE *NAME
#define AMS_SVC_USER_INPTR_HANDLER(TYPE, NAME) ::ams::svc::UserPointer NAME
#define AMS_SVC_USER_OUTPTR_HANDLER(TYPE, NAME) ::ams::svc::UserPointer NAME
#define AMS_SVC_FOREACH_USER_DEFINITION(HANDLER, NAMESPACE) AMS_SVC_FOREACH_DEFINITION_IMPL(HANDLER, NAMESPACE, AMS_SVC_USER_INPUT_HANDLER, AMS_SVC_USER_OUTPUT_HANDLER, AMS_SVC_USER_INPTR_HANDLER, AMS_SVC_USER_OUTPTR_HANDLER)
#define AMS_SVC_FOREACH_KERN_DEFINITION(HANDLER, NAMESPACE) AMS_SVC_FOREACH_DEFINITION_IMPL(HANDLER, NAMESPACE, AMS_SVC_KERN_INPUT_HANDLER, AMS_SVC_KERN_OUTPUT_HANDLER, AMS_SVC_KERN_INPTR_HANDLER, AMS_SVC_KERN_OUTPTR_HANDLER)
#define AMS_SVC_DECLARE_FUNCTION_PROTOTYPE(ID, RETURN_TYPE, NAME, ...) \
RETURN_TYPE NAME(__VA_ARGS__);
namespace ams::svc {
#define AMS_SVC_DEFINE_ID_ENUM_MEMBER(ID, RETURN_TYPE, NAME, ...) \
SvcId_##NAME = ID,
enum SvcId : u32 {
AMS_SVC_FOREACH_KERN_DEFINITION(AMS_SVC_DEFINE_ID_ENUM_MEMBER, _)
};
#undef AMS_SVC_DEFINE_ID_ENUM_MEMBER
}
#ifdef ATMOSPHERE_IS_STRATOSPHERE
namespace ams::svc {
namespace aarch64::lp64 {
AMS_SVC_FOREACH_USER_DEFINITION(AMS_SVC_DECLARE_FUNCTION_PROTOTYPE, lp64)
}
namespace aarch64::ilp32 {
AMS_SVC_FOREACH_USER_DEFINITION(AMS_SVC_DECLARE_FUNCTION_PROTOTYPE, ilp32)
}
namespace aarch32 {
AMS_SVC_FOREACH_USER_DEFINITION(AMS_SVC_DECLARE_FUNCTION_PROTOTYPE, ilp32)
}
}
/* NOTE: Change this to 1 to test the SVC definitions for user-pointer validity. */
#if 0
namespace ams::svc::test {
namespace impl {
template
struct Validator {
private:
std::array m_valid;
public:
constexpr Validator(Ts... args) : m_valid{static_cast(args)...} { /* ... */ }
constexpr bool IsValid() const {
for (size_t i = 0; i < sizeof...(Ts); i++) {
if (!m_valid[i]) {
return false;
}
}
return true;
}
};
}
#define AMS_SVC_TEST_EMPTY_HANDLER(TYPE, NAME) true
#define AMS_SVC_TEST_INPTR_HANDLER(TYPE, NAME) (sizeof(::ams::svc::UserPointer) == sizeof(uintptr_t) && std::is_trivially_destructible<::ams::svc::UserPointer>::value)
#define AMS_SVC_TEST_OUTPTR_HANDLER(TYPE, NAME) (sizeof(::ams::svc::UserPointer) == sizeof(uintptr_t) && std::is_trivially_destructible<::ams::svc::UserPointer>::value)
#define AMS_SVC_TEST_VERIFY_USER_POINTERS(ID, RETURN_TYPE, NAME, ...) \
static_assert(impl::Validator(__VA_ARGS__).IsValid(), "Invalid User Pointer in svc::" #NAME);
AMS_SVC_FOREACH_DEFINITION_IMPL(AMS_SVC_TEST_VERIFY_USER_POINTERS, lp64, AMS_SVC_TEST_EMPTY_HANDLER, AMS_SVC_TEST_EMPTY_HANDLER, AMS_SVC_TEST_INPTR_HANDLER, AMS_SVC_TEST_OUTPTR_HANDLER);
AMS_SVC_FOREACH_DEFINITION_IMPL(AMS_SVC_TEST_VERIFY_USER_POINTERS, ilp32, AMS_SVC_TEST_EMPTY_HANDLER, AMS_SVC_TEST_EMPTY_HANDLER, AMS_SVC_TEST_INPTR_HANDLER, AMS_SVC_TEST_OUTPTR_HANDLER);
#undef AMS_SVC_TEST_VERIFY_USER_POINTERS
#undef AMS_SVC_TEST_INPTR_HANDLER
#undef AMS_SVC_TEST_OUTPTR_HANDLER
#undef AMS_SVC_TEST_EMPTY_HANDLER
}
#endif
#endif /* ATMOSPHERE_IS_STRATOSPHERE */