mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-29 16:25:36 +03:00
Enable Wconversion and fix warnings produced
This commit is contained in:
parent
315d2dc26c
commit
70d1b4994c
@ -232,4 +232,4 @@ add_library(skyline SHARED
|
|||||||
target_include_directories(skyline PRIVATE ${source_DIR}/skyline)
|
target_include_directories(skyline PRIVATE ${source_DIR}/skyline)
|
||||||
# target_precompile_headers(skyline PRIVATE ${source_DIR}/skyline/common.h) # PCH will currently break Intellisense
|
# target_precompile_headers(skyline PRIVATE ${source_DIR}/skyline/common.h) # PCH will currently break Intellisense
|
||||||
target_link_libraries(skyline android perfetto fmt lz4_static tzcode oboe vkma mbedcrypto opus Boost::container)
|
target_link_libraries(skyline android perfetto fmt lz4_static tzcode oboe vkma mbedcrypto opus Boost::container)
|
||||||
target_compile_options(skyline PRIVATE -Wall -Wno-unknown-attributes -Wno-c++20-extensions -Wno-c++17-extensions -Wno-c99-designator -Wno-reorder -Wno-missing-braces -Wno-unused-variable -Wno-unused-private-field -Wno-dangling-else)
|
target_compile_options(skyline PRIVATE -Wall -Wno-unknown-attributes -Wno-c++20-extensions -Wno-c++17-extensions -Wno-c99-designator -Wno-reorder -Wno-missing-braces -Wno-unused-variable -Wno-unused-private-field -Wno-dangling-else -Wconversion)
|
||||||
|
@ -67,7 +67,8 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
|||||||
jobject assetManager
|
jobject assetManager
|
||||||
) {
|
) {
|
||||||
skyline::signal::ScopedStackBlocker stackBlocker; // We do not want anything to unwind past JNI code as there are invalid stack frames which can lead to a segmentation fault
|
skyline::signal::ScopedStackBlocker stackBlocker; // We do not want anything to unwind past JNI code as there are invalid stack frames which can lead to a segmentation fault
|
||||||
Fps = AverageFrametimeMs = AverageFrametimeDeviationMs = 0;
|
Fps = 0;
|
||||||
|
AverageFrametimeMs = AverageFrametimeDeviationMs = 0.0f;
|
||||||
|
|
||||||
pthread_setname_np(pthread_self(), "EmuMain");
|
pthread_setname_np(pthread_self(), "EmuMain");
|
||||||
|
|
||||||
@ -178,7 +179,7 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_updatePerformanceSt
|
|||||||
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setController(JNIEnv *, jobject, jint index, jint type, jint partnerIndex) {
|
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setController(JNIEnv *, jobject, jint index, jint type, jint partnerIndex) {
|
||||||
auto input{InputWeak.lock()};
|
auto input{InputWeak.lock()};
|
||||||
std::lock_guard guard(input->npad.mutex);
|
std::lock_guard guard(input->npad.mutex);
|
||||||
input->npad.controllers[index] = skyline::input::GuestController{static_cast<skyline::input::NpadControllerType>(type), static_cast<skyline::i8>(partnerIndex)};
|
input->npad.controllers[static_cast<size_t>(index)] = skyline::input::GuestController{static_cast<skyline::input::NpadControllerType>(type), static_cast<skyline::i8>(partnerIndex)};
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_updateControllers(JNIEnv *, jobject) {
|
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_updateControllers(JNIEnv *, jobject) {
|
||||||
@ -189,7 +190,7 @@ extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setButtonSt
|
|||||||
auto input{InputWeak.lock()};
|
auto input{InputWeak.lock()};
|
||||||
if (!input)
|
if (!input)
|
||||||
return; // We don't mind if we miss button updates while input hasn't been initialized
|
return; // We don't mind if we miss button updates while input hasn't been initialized
|
||||||
auto device{input->npad.controllers[index].device};
|
auto device{input->npad.controllers[static_cast<size_t>(index)].device};
|
||||||
if (device)
|
if (device)
|
||||||
device->SetButtonState(skyline::input::NpadButton{.raw = static_cast<skyline::u64>(mask)}, pressed);
|
device->SetButtonState(skyline::input::NpadButton{.raw = static_cast<skyline::u64>(mask)}, pressed);
|
||||||
}
|
}
|
||||||
@ -198,7 +199,7 @@ extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setAxisValu
|
|||||||
auto input{InputWeak.lock()};
|
auto input{InputWeak.lock()};
|
||||||
if (!input)
|
if (!input)
|
||||||
return; // We don't mind if we miss axis updates while input hasn't been initialized
|
return; // We don't mind if we miss axis updates while input hasn't been initialized
|
||||||
auto device{input->npad.controllers[index].device};
|
auto device{input->npad.controllers[static_cast<size_t>(index)].device};
|
||||||
if (device)
|
if (device)
|
||||||
device->SetAxisValue(static_cast<skyline::input::NpadAxisId>(axis), value);
|
device->SetAxisValue(static_cast<skyline::input::NpadAxisId>(axis), value);
|
||||||
}
|
}
|
||||||
@ -211,7 +212,8 @@ extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setTouchSta
|
|||||||
return; // We don't mind if we miss touch updates while input hasn't been initialized
|
return; // We don't mind if we miss touch updates while input hasn't been initialized
|
||||||
jboolean isCopy{false};
|
jboolean isCopy{false};
|
||||||
|
|
||||||
skyline::span<Point> points(reinterpret_cast<Point *>(env->GetIntArrayElements(pointsJni, &isCopy)), env->GetArrayLength(pointsJni) / (sizeof(Point) / sizeof(jint)));
|
skyline::span<Point> points(reinterpret_cast<Point *>(env->GetIntArrayElements(pointsJni, &isCopy)),
|
||||||
|
static_cast<size_t>(env->GetArrayLength(pointsJni)) / (sizeof(Point) / sizeof(jint)));
|
||||||
input->touch.SetState(points);
|
input->touch.SetState(points);
|
||||||
env->ReleaseIntArrayElements(pointsJni, reinterpret_cast<jint *>(points.data()), JNI_ABORT);
|
env->ReleaseIntArrayElements(pointsJni, reinterpret_cast<jint *>(points.data()), JNI_ABORT);
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,8 @@ extern "C" JNIEXPORT jint JNICALL Java_emu_skyline_loader_RomFile_populate(JNIEn
|
|||||||
env->SetObjectField(thiz, applicationAuthorField, env->NewStringUTF(loader->nacp->GetApplicationPublisher(language).c_str()));
|
env->SetObjectField(thiz, applicationAuthorField, env->NewStringUTF(loader->nacp->GetApplicationPublisher(language).c_str()));
|
||||||
|
|
||||||
auto icon{loader->GetIcon(language)};
|
auto icon{loader->GetIcon(language)};
|
||||||
jbyteArray iconByteArray{env->NewByteArray(icon.size())};
|
jbyteArray iconByteArray{env->NewByteArray(static_cast<jsize>(icon.size()))};
|
||||||
env->SetByteArrayRegion(iconByteArray, 0, icon.size(), reinterpret_cast<const jbyte *>(icon.data()));
|
env->SetByteArrayRegion(iconByteArray, 0, static_cast<jsize>(icon.size()), reinterpret_cast<const jbyte *>(icon.data()));
|
||||||
env->SetObjectField(thiz, rawIconField, iconByteArray);
|
env->SetObjectField(thiz, rawIconField, iconByteArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ namespace skyline::audio {
|
|||||||
|
|
||||||
oboe::DataCallbackResult Audio::onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) {
|
oboe::DataCallbackResult Audio::onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) {
|
||||||
auto destBuffer{static_cast<i16 *>(audioData)};
|
auto destBuffer{static_cast<i16 *>(audioData)};
|
||||||
auto streamSamples{static_cast<size_t>(numFrames) * audioStream->getChannelCount()};
|
auto streamSamples{static_cast<size_t>(numFrames) * static_cast<size_t>(audioStream->getChannelCount())};
|
||||||
size_t writtenSamples{};
|
size_t writtenSamples{};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -54,7 +54,7 @@ namespace skyline::audio {
|
|||||||
|
|
||||||
auto trackSamples{track->samples.Read(span(destBuffer, streamSamples), [](i16 *source, i16 *destination) {
|
auto trackSamples{track->samples.Read(span(destBuffer, streamSamples), [](i16 *source, i16 *destination) {
|
||||||
*destination = Saturate<i16, i32>(static_cast<u32>(*destination) + static_cast<u32>(*source));
|
*destination = Saturate<i16, i32>(static_cast<u32>(*destination) + static_cast<u32>(*source));
|
||||||
}, writtenSamples)};
|
}, static_cast<ssize_t>(writtenSamples))};
|
||||||
|
|
||||||
writtenSamples = std::max(trackSamples, writtenSamples);
|
writtenSamples = std::max(trackSamples, writtenSamples);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ namespace skyline {
|
|||||||
private:
|
private:
|
||||||
std::mutex mutex; //!< Synchronizes all output I/O to ensure there are no races
|
std::mutex mutex; //!< Synchronizes all output I/O to ensure there are no races
|
||||||
std::ofstream logFile; //!< An output stream to the log file
|
std::ofstream logFile; //!< An output stream to the log file
|
||||||
u64 start; //!< A timestamp in milliseconds for when the logger was started, this is used as the base for all log timestamps
|
i64 start; //!< A timestamp in milliseconds for when the logger was started, this is used as the base for all log timestamps
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class LogLevel {
|
enum class LogLevel {
|
||||||
|
@ -37,10 +37,10 @@ namespace skyline {
|
|||||||
|
|
||||||
namespace constant {
|
namespace constant {
|
||||||
// Time
|
// Time
|
||||||
constexpr u64 NsInMicrosecond{1000}; //!< The amount of nanoseconds in a microsecond
|
constexpr i64 NsInMicrosecond{1000}; //!< The amount of nanoseconds in a microsecond
|
||||||
constexpr u64 NsInSecond{1000000000}; //!< The amount of nanoseconds in a second
|
constexpr i64 NsInSecond{1000000000}; //!< The amount of nanoseconds in a second
|
||||||
constexpr u64 NsInMillisecond{1000000}; //!< The amount of nanoseconds in a millisecond
|
constexpr i64 NsInMillisecond{1000000}; //!< The amount of nanoseconds in a millisecond
|
||||||
constexpr u64 NsInDay{86400000000000UL}; //!< The amount of nanoseconds in a day
|
constexpr i64 NsInDay{86400000000000UL}; //!< The amount of nanoseconds in a day
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
|
@ -55,11 +55,11 @@ namespace skyline {
|
|||||||
copyFunction(source, destination);
|
copyFunction(source, destination);
|
||||||
|
|
||||||
if (copyOffset != -1) {
|
if (copyOffset != -1) {
|
||||||
std::memcpy(pointer + copyOffset, start + copyOffset, (sizeEnd - copyOffset) * sizeof(Type));
|
std::memcpy(pointer + copyOffset, start + copyOffset, static_cast<size_t>(sizeEnd - copyOffset) * sizeof(Type));
|
||||||
copyOffset -= sizeEnd;
|
copyOffset -= sizeEnd;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::memcpy(pointer, start, sizeEnd * sizeof(Type));
|
std::memcpy(pointer, start, static_cast<size_t>(sizeEnd) * sizeof(Type));
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer += sizeEnd;
|
pointer += sizeEnd;
|
||||||
@ -72,9 +72,9 @@ namespace skyline {
|
|||||||
copyFunction(source, destination);
|
copyFunction(source, destination);
|
||||||
|
|
||||||
if (copyOffset != -1)
|
if (copyOffset != -1)
|
||||||
std::memcpy(array.begin() + copyOffset, pointer + copyOffset, (sizeBegin - copyOffset) * sizeof(Type));
|
std::memcpy(array.begin() + copyOffset, pointer + copyOffset, static_cast<size_t>(sizeBegin - copyOffset) * sizeof(Type));
|
||||||
} else {
|
} else {
|
||||||
std::memcpy(pointer, array.begin(), sizeBegin * sizeof(Type));
|
std::memcpy(pointer, array.begin(), static_cast<size_t>(sizeBegin) * sizeof(Type));
|
||||||
}
|
}
|
||||||
|
|
||||||
start = array.begin() + sizeBegin;
|
start = array.begin() + sizeBegin;
|
||||||
@ -99,7 +99,7 @@ namespace skyline {
|
|||||||
while (size) {
|
while (size) {
|
||||||
if (start <= end && end != array.end()) {
|
if (start <= end && end != array.end()) {
|
||||||
auto sizeEnd{std::min(array.end() - end, size)};
|
auto sizeEnd{std::min(array.end() - end, size)};
|
||||||
std::memcpy(end, pointer, sizeEnd * sizeof(Type));
|
std::memcpy(end, pointer, static_cast<size_t>(sizeEnd) * sizeof(Type));
|
||||||
|
|
||||||
pointer += sizeEnd;
|
pointer += sizeEnd;
|
||||||
size -= sizeEnd;
|
size -= sizeEnd;
|
||||||
@ -110,7 +110,7 @@ namespace skyline {
|
|||||||
auto sizePostStart{std::min(array.end() - start, size - sizePreStart)};
|
auto sizePostStart{std::min(array.end() - start, size - sizePreStart)};
|
||||||
|
|
||||||
if (sizePreStart)
|
if (sizePreStart)
|
||||||
std::memcpy((end == array.end()) ? array.begin() : end, pointer, sizePreStart * sizeof(Type));
|
std::memcpy((end == array.end()) ? array.begin() : end, pointer, static_cast<size_t>(sizePreStart) * sizeof(Type));
|
||||||
|
|
||||||
if (end == array.end())
|
if (end == array.end())
|
||||||
end = array.begin() + sizePreStart;
|
end = array.begin() + sizePreStart;
|
||||||
@ -121,7 +121,7 @@ namespace skyline {
|
|||||||
size -= sizePreStart;
|
size -= sizePreStart;
|
||||||
|
|
||||||
if (sizePostStart)
|
if (sizePostStart)
|
||||||
std::memcpy(end, pointer, sizePostStart * sizeof(Type));
|
std::memcpy(end, pointer, static_cast<size_t>(sizePostStart) * sizeof(Type));
|
||||||
|
|
||||||
if (start == array.end())
|
if (start == array.end())
|
||||||
start = array.begin() + sizePostStart;
|
start = array.begin() + sizePostStart;
|
||||||
|
@ -157,11 +157,11 @@ namespace skyline::signal {
|
|||||||
if (TlsRestorer)
|
if (TlsRestorer)
|
||||||
tls = TlsRestorer();
|
tls = TlsRestorer();
|
||||||
|
|
||||||
auto handler{ThreadSignalHandlers.at(signal)};
|
auto handler{ThreadSignalHandlers.at(static_cast<size_t>(signal))};
|
||||||
if (handler) {
|
if (handler) {
|
||||||
handler(signal, info, context, &tls);
|
handler(signal, info, context, &tls);
|
||||||
} else {
|
} else {
|
||||||
auto defaultHandler{DefaultSignalHandlers.at(signal).function};
|
auto defaultHandler{DefaultSignalHandlers.at(static_cast<size_t>(signal)).function};
|
||||||
if (defaultHandler)
|
if (defaultHandler)
|
||||||
defaultHandler(signal, info, context);
|
defaultHandler(signal, info, context);
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ namespace skyline::signal {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (int signal : signals) {
|
for (int signal : signals) {
|
||||||
std::call_once(signalHandlerOnce[signal], [signal, &action]() {
|
std::call_once(signalHandlerOnce[static_cast<size_t>(signal)], [signal, &action]() {
|
||||||
struct sigaction oldAction;
|
struct sigaction oldAction;
|
||||||
Sigaction(signal, &action, &oldAction);
|
Sigaction(signal, &action, &oldAction);
|
||||||
if (oldAction.sa_flags) {
|
if (oldAction.sa_flags) {
|
||||||
@ -189,9 +189,9 @@ namespace skyline::signal {
|
|||||||
throw exception("Old sigaction flags aren't equivalent to the replaced signal: {:#b} | {:#b}", oldAction.sa_flags, action.sa_flags);
|
throw exception("Old sigaction flags aren't equivalent to the replaced signal: {:#b} | {:#b}", oldAction.sa_flags, action.sa_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultSignalHandlers.at(signal).function = (oldAction.sa_flags & SA_SIGINFO) ? oldAction.sa_sigaction : reinterpret_cast<void (*)(int, struct siginfo *, void *)>(oldAction.sa_handler);
|
DefaultSignalHandlers.at(static_cast<size_t>(signal)).function = (oldAction.sa_flags & SA_SIGINFO) ? oldAction.sa_sigaction : reinterpret_cast<void (*)(int, struct siginfo *, void *)>(oldAction.sa_handler);
|
||||||
});
|
});
|
||||||
ThreadSignalHandlers.at(signal) = function;
|
ThreadSignalHandlers.at(static_cast<size_t>(signal)) = function;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ namespace skyline {
|
|||||||
* @param nullTerminated If true and the string is null-terminated, a view of it will be returned (not including the null terminator itself), otherwise the entire span will be returned as a string view
|
* @param nullTerminated If true and the string is null-terminated, a view of it will be returned (not including the null terminator itself), otherwise the entire span will be returned as a string view
|
||||||
*/
|
*/
|
||||||
constexpr std::string_view as_string(bool nullTerminated = false) {
|
constexpr std::string_view as_string(bool nullTerminated = false) {
|
||||||
return std::string_view(reinterpret_cast<const char *>(span::data()), nullTerminated ? (std::find(span::begin(), span::end(), 0) - span::begin()) : span::size_bytes());
|
return std::string_view(reinterpret_cast<const char *>(span::data()), nullTerminated ? static_cast<size_t>(std::find(span::begin(), span::end(), 0) - span::begin()) : span::size_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Out, size_t OutExtent = std::dynamic_extent, bool SkipAlignmentCheck = false>
|
template<typename Out, size_t OutExtent = std::dynamic_extent, bool SkipAlignmentCheck = false>
|
||||||
|
@ -13,12 +13,12 @@ namespace skyline::util {
|
|||||||
* @brief Returns the current time in nanoseconds
|
* @brief Returns the current time in nanoseconds
|
||||||
* @return The current time in nanoseconds
|
* @return The current time in nanoseconds
|
||||||
*/
|
*/
|
||||||
inline u64 GetTimeNs() {
|
inline i64 GetTimeNs() {
|
||||||
u64 frequency;
|
u64 frequency;
|
||||||
asm("MRS %0, CNTFRQ_EL0" : "=r"(frequency));
|
asm("MRS %0, CNTFRQ_EL0" : "=r"(frequency));
|
||||||
u64 ticks;
|
u64 ticks;
|
||||||
asm("MRS %0, CNTVCT_EL0" : "=r"(ticks));
|
asm("MRS %0, CNTVCT_EL0" : "=r"(ticks));
|
||||||
return ((ticks / frequency) * constant::NsInSecond) + (((ticks % frequency) * constant::NsInSecond + (frequency / 2)) / frequency);
|
return static_cast<i64>(((ticks / frequency) * constant::NsInSecond) + (((ticks % frequency) * constant::NsInSecond + (frequency / 2)) / frequency));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,18 +52,19 @@ namespace skyline::util {
|
|||||||
if constexpr (std::is_pointer<Return>::value)
|
if constexpr (std::is_pointer<Return>::value)
|
||||||
return reinterpret_cast<Return>(item);
|
return reinterpret_cast<Return>(item);
|
||||||
else
|
else
|
||||||
return item;
|
return static_cast<Return>(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept IsPointerOrIntegral = std::is_integral_v<T> || std::is_pointer_v<T>;
|
concept IsPointerOrUnsignedIntegral = (std::is_unsigned_v<T> && std::is_integral_v<T>) || std::is_pointer_v<T>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The value aligned up to the next multiple
|
* @return The value aligned up to the next multiple
|
||||||
* @note The multiple needs to be a power of 2
|
* @note The multiple needs to be a power of 2
|
||||||
*/
|
*/
|
||||||
template<typename TypeVal, typename TypeMul>
|
template<typename TypeVal>
|
||||||
constexpr TypeVal AlignUp(TypeVal value, TypeMul multiple) {
|
requires IsPointerOrUnsignedIntegral<TypeVal>
|
||||||
|
constexpr TypeVal AlignUp(TypeVal value, size_t multiple) {
|
||||||
multiple--;
|
multiple--;
|
||||||
return ValuePointer<TypeVal>((PointerValue(value) + multiple) & ~(multiple));
|
return ValuePointer<TypeVal>((PointerValue(value) + multiple) & ~(multiple));
|
||||||
}
|
}
|
||||||
@ -72,17 +73,18 @@ namespace skyline::util {
|
|||||||
* @return The value aligned down to the previous multiple
|
* @return The value aligned down to the previous multiple
|
||||||
* @note The multiple needs to be a power of 2
|
* @note The multiple needs to be a power of 2
|
||||||
*/
|
*/
|
||||||
template<typename TypeVal, typename TypeMul>
|
template<typename TypeVal>
|
||||||
constexpr TypeVal AlignDown(TypeVal value, TypeMul multiple) {
|
requires IsPointerOrUnsignedIntegral<TypeVal>
|
||||||
|
constexpr TypeVal AlignDown(TypeVal value, size_t multiple) {
|
||||||
return ValuePointer<TypeVal>(PointerValue(value) & ~(multiple - 1));
|
return ValuePointer<TypeVal>(PointerValue(value) & ~(multiple - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return If the address is aligned with the multiple
|
* @return If the address is aligned with the multiple
|
||||||
*/
|
*/
|
||||||
template<typename TypeVal, typename TypeMul>
|
template<typename TypeVal>
|
||||||
requires (IsPointerOrIntegral<TypeVal> && IsPointerOrIntegral<TypeMul>)
|
requires IsPointerOrUnsignedIntegral<TypeVal>
|
||||||
constexpr bool IsAligned(TypeVal value, TypeMul multiple) {
|
constexpr bool IsAligned(TypeVal value, size_t multiple) {
|
||||||
if ((multiple & (multiple - 1)) == 0)
|
if ((multiple & (multiple - 1)) == 0)
|
||||||
return !(PointerValue(value) & (multiple - 1U));
|
return !(PointerValue(value) & (multiple - 1U));
|
||||||
else
|
else
|
||||||
@ -90,13 +92,13 @@ namespace skyline::util {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename TypeVal>
|
template<typename TypeVal>
|
||||||
requires IsPointerOrIntegral<TypeVal>
|
requires IsPointerOrUnsignedIntegral<TypeVal>
|
||||||
constexpr bool IsPageAligned(TypeVal value) {
|
constexpr bool IsPageAligned(TypeVal value) {
|
||||||
return IsAligned(value, PAGE_SIZE);
|
return IsAligned(value, PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TypeVal>
|
template<typename TypeVal>
|
||||||
requires IsPointerOrIntegral<TypeVal>
|
requires IsPointerOrUnsignedIntegral<TypeVal>
|
||||||
constexpr bool IsWordAligned(TypeVal value) {
|
constexpr bool IsWordAligned(TypeVal value) {
|
||||||
return IsAligned(value, WORD_BIT / 8);
|
return IsAligned(value, WORD_BIT / 8);
|
||||||
}
|
}
|
||||||
@ -136,7 +138,7 @@ namespace skyline::util {
|
|||||||
std::array<u8, Size> result;
|
std::array<u8, Size> result;
|
||||||
for (size_t i{}; i < Size; i++) {
|
for (size_t i{}; i < Size; i++) {
|
||||||
size_t index{i * 2};
|
size_t index{i * 2};
|
||||||
result[i] = (HexDigitToNibble(string[index]) << 4) | HexDigitToNibble(string[index + 1]);
|
result[i] = static_cast<u8>(HexDigitToNibble(string[index]) << 4) | HexDigitToNibble(string[index + 1]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ namespace skyline::crypto {
|
|||||||
if (mbedtls_cipher_setup(&decryptContext, mbedtls_cipher_info_from_type(type)) != 0)
|
if (mbedtls_cipher_setup(&decryptContext, mbedtls_cipher_info_from_type(type)) != 0)
|
||||||
throw exception("Failed to setup decryption context");
|
throw exception("Failed to setup decryption context");
|
||||||
|
|
||||||
if (mbedtls_cipher_setkey(&decryptContext, key.data(), key.size() * 8, MBEDTLS_DECRYPT) != 0)
|
if (mbedtls_cipher_setkey(&decryptContext, key.data(), static_cast<int>(key.size() * 8), MBEDTLS_DECRYPT) != 0)
|
||||||
throw exception("Failed to set key for decryption context");
|
throw exception("Failed to set key for decryption context");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ namespace skyline::crypto {
|
|||||||
if (keyEnd == lineEnd)
|
if (keyEnd == lineEnd)
|
||||||
throw exception("Invalid key file");
|
throw exception("Invalid key file");
|
||||||
|
|
||||||
std::string_view key(&*lineStart, keyEnd - lineStart);
|
std::string_view key(&*lineStart, static_cast<size_t>(keyEnd - lineStart));
|
||||||
std::string_view value(&*(keyEnd + 1), lineEnd - keyEnd - 1);
|
std::string_view value(&*(keyEnd + 1), static_cast<size_t>(lineEnd - keyEnd - 1));
|
||||||
(this->*callback)(key, value);
|
(this->*callback)(key, value);
|
||||||
|
|
||||||
lineStart = lineEnd + 1;
|
lineStart = lineEnd + 1;
|
||||||
|
@ -8,7 +8,7 @@ namespace skyline::gpu {
|
|||||||
vk::raii::Instance GPU::CreateInstance(const DeviceState &state, const vk::raii::Context &context) {
|
vk::raii::Instance GPU::CreateInstance(const DeviceState &state, const vk::raii::Context &context) {
|
||||||
vk::ApplicationInfo applicationInfo{
|
vk::ApplicationInfo applicationInfo{
|
||||||
.pApplicationName = "Skyline",
|
.pApplicationName = "Skyline",
|
||||||
.applicationVersion = state.jvm->GetVersionCode(), // Get the application version from JNI
|
.applicationVersion = static_cast<uint32_t>(state.jvm->GetVersionCode()), // Get the application version from JNI
|
||||||
.pEngineName = "FTX1", // "Fast Tegra X1"
|
.pEngineName = "FTX1", // "Fast Tegra X1"
|
||||||
.apiVersion = VkApiVersion,
|
.apiVersion = VkApiVersion,
|
||||||
};
|
};
|
||||||
@ -111,7 +111,7 @@ namespace skyline::gpu {
|
|||||||
#undef IGNORE_TYPE
|
#undef IGNORE_TYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
logger->Write(severityLookup.at(std::countr_zero(static_cast<u32>(flags))), util::Format("Vk{}:{}[0x{:X}]:I{}:L{}: {}", layerPrefix, vk::to_string(vk::DebugReportObjectTypeEXT(objectType)), object, messageCode, location, message));
|
logger->Write(severityLookup.at(static_cast<size_t>(std::countr_zero(static_cast<u32>(flags)))), util::Format("Vk{}:{}[0x{:X}]:I{}:L{}: {}", layerPrefix, vk::to_string(vk::DebugReportObjectTypeEXT(objectType)), object, messageCode, location, message));
|
||||||
|
|
||||||
return VK_FALSE;
|
return VK_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ namespace skyline::gpu::interconnect::node {
|
|||||||
return static_cast<u32>(attachments.size() - 1);
|
return static_cast<u32>(attachments.size() - 1);
|
||||||
} else {
|
} else {
|
||||||
// If we've got a match from a previous subpass, we need to preserve the attachment till the current subpass
|
// If we've got a match from a previous subpass, we need to preserve the attachment till the current subpass
|
||||||
auto attachmentIndex{std::distance(attachments.begin(), attachment)};
|
auto attachmentIndex{static_cast<u32>(std::distance(attachments.begin(), attachment))};
|
||||||
|
|
||||||
auto it{subpassDescriptions.begin()};
|
auto it{subpassDescriptions.begin()};
|
||||||
auto getSubpassAttachmentRange{[this] (const vk::SubpassDescription& subpassDescription) {
|
auto getSubpassAttachmentRange{[this] (const vk::SubpassDescription& subpassDescription) {
|
||||||
@ -74,7 +74,7 @@ namespace skyline::gpu::interconnect::node {
|
|||||||
continue; // If a subpass uses an attachment then it doesn't need to be preserved
|
continue; // If a subpass uses an attachment then it doesn't need to be preserved
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &subpassPreserveAttachments{preserveAttachmentReferences[std::distance(subpassDescriptions.begin(), it)]};
|
auto &subpassPreserveAttachments{preserveAttachmentReferences[static_cast<size_t>(std::distance(subpassDescriptions.begin(), it))]};
|
||||||
if (std::find(subpassPreserveAttachments.begin(), subpassPreserveAttachments.end(), attachmentIndex) != subpassPreserveAttachments.end())
|
if (std::find(subpassPreserveAttachments.begin(), subpassPreserveAttachments.end(), attachmentIndex) != subpassPreserveAttachments.end())
|
||||||
subpassPreserveAttachments.push_back(attachmentIndex);
|
subpassPreserveAttachments.push_back(attachmentIndex);
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ namespace skyline::gpu::interconnect::node {
|
|||||||
else
|
else
|
||||||
subpassDescription.pDepthStencilAttachment = nullptr;
|
subpassDescription.pDepthStencilAttachment = nullptr;
|
||||||
|
|
||||||
subpassDescription.preserveAttachmentCount = preserveAttachmentIt->size();
|
subpassDescription.preserveAttachmentCount = static_cast<u32>(preserveAttachmentIt->size());
|
||||||
subpassDescription.pPreserveAttachments = preserveAttachmentIt->data();
|
subpassDescription.pPreserveAttachments = preserveAttachmentIt->data();
|
||||||
preserveAttachmentIt++;
|
preserveAttachmentIt++;
|
||||||
}
|
}
|
||||||
|
@ -186,9 +186,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
|
|
||||||
void SetRenderTargetBaseLayer(size_t index, u32 baseArrayLayer) {
|
void SetRenderTargetBaseLayer(size_t index, u32 baseArrayLayer) {
|
||||||
auto &renderTarget{renderTargets.at(index)};
|
auto &renderTarget{renderTargets.at(index)};
|
||||||
renderTarget.guest.baseArrayLayer = baseArrayLayer;
|
|
||||||
if (baseArrayLayer > std::numeric_limits<u16>::max())
|
if (baseArrayLayer > std::numeric_limits<u16>::max())
|
||||||
throw exception("Base array layer ({}) exceeds the range of array count ({}) (with layer count = {})", baseArrayLayer, std::numeric_limits<u16>::max(), renderTarget.guest.layerCount);
|
throw exception("Base array layer ({}) exceeds the range of array count ({}) (with layer count = {})", baseArrayLayer, std::numeric_limits<u16>::max(), renderTarget.guest.layerCount);
|
||||||
|
|
||||||
|
renderTarget.guest.baseArrayLayer = static_cast<u16>(baseArrayLayer);
|
||||||
renderTarget.view.reset();
|
renderTarget.view.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,8 +264,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
auto scissor{scissors.at(renderTargetIndex)};
|
auto scissor{scissors.at(renderTargetIndex)};
|
||||||
scissor.extent.width = std::min(renderTarget.backing->dimensions.width - scissor.offset.x, scissor.extent.width);
|
scissor.extent.width = static_cast<u32>(std::min(static_cast<i32>(renderTarget.backing->dimensions.width) - scissor.offset.x,
|
||||||
scissor.extent.height = std::min(renderTarget.backing->dimensions.height - scissor.offset.y, scissor.extent.height);
|
static_cast<i32>(scissor.extent.width)));
|
||||||
|
scissor.extent.height = static_cast<u32>(std::min(static_cast<i32>(renderTarget.backing->dimensions.height) - scissor.offset.y,
|
||||||
|
static_cast<i32>(scissor.extent.height)));
|
||||||
|
|
||||||
if (scissor.extent.width == 0 || scissor.extent.height == 0)
|
if (scissor.extent.width == 0 || scissor.extent.height == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -210,7 +210,7 @@ namespace skyline::gpu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresentationEngine::Present(const std::shared_ptr<Texture> &texture, u64 timestamp, u64 swapInterval, AndroidRect crop, NativeWindowScalingMode scalingMode, NativeWindowTransform transform, u64 &frameId) {
|
void PresentationEngine::Present(const std::shared_ptr<Texture> &texture, i64 timestamp, u64 swapInterval, AndroidRect crop, NativeWindowScalingMode scalingMode, NativeWindowTransform transform, u64 &frameId) {
|
||||||
std::unique_lock lock(mutex);
|
std::unique_lock lock(mutex);
|
||||||
surfaceCondition.wait(lock, [this]() { return vkSurface.has_value(); });
|
surfaceCondition.wait(lock, [this]() { return vkSurface.has_value(); });
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ namespace skyline::gpu {
|
|||||||
// If the timestamp is specified, we need to convert it from the util::GetTimeNs base to the CLOCK_MONOTONIC one
|
// If the timestamp is specified, we need to convert it from the util::GetTimeNs base to the CLOCK_MONOTONIC one
|
||||||
// We do so by getting an offset from the current time in nanoseconds and then adding it to the current time in CLOCK_MONOTONIC
|
// We do so by getting an offset from the current time in nanoseconds and then adding it to the current time in CLOCK_MONOTONIC
|
||||||
// Note: It's important we do this right before present as going past the timestamp could lead to fewer Binder IPC calls
|
// Note: It's important we do this right before present as going past the timestamp could lead to fewer Binder IPC calls
|
||||||
auto current{util::GetTimeNs()};
|
i64 current{util::GetTimeNs()};
|
||||||
if (current < timestamp) {
|
if (current < timestamp) {
|
||||||
timespec time;
|
timespec time;
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &time))
|
if (clock_gettime(CLOCK_MONOTONIC, &time))
|
||||||
@ -270,7 +270,7 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
if (swapInterval > 1)
|
if (swapInterval > 1)
|
||||||
// If we have a swap interval above 1 we have to adjust the timestamp to emulate the swap interval
|
// If we have a swap interval above 1 we have to adjust the timestamp to emulate the swap interval
|
||||||
timestamp = std::max(timestamp, lastChoreographerTime + (refreshCycleDuration * swapInterval * 2));
|
timestamp = std::max(timestamp, lastChoreographerTime + (refreshCycleDuration * static_cast<i64>(swapInterval) * 2));
|
||||||
|
|
||||||
auto lastTimestamp{std::exchange(windowLastTimestamp, timestamp)};
|
auto lastTimestamp{std::exchange(windowLastTimestamp, timestamp)};
|
||||||
if (!timestamp && lastTimestamp)
|
if (!timestamp && lastTimestamp)
|
||||||
@ -293,8 +293,8 @@ namespace skyline::gpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (frameTimestamp) {
|
if (frameTimestamp) {
|
||||||
i64 now{static_cast<i64>(util::GetTimeNs())};
|
i64 now{util::GetTimeNs()};
|
||||||
i64 sampleWeight{static_cast<i64>(swapInterval ? constant::NsInSecond / (refreshCycleDuration * swapInterval) : 10)}; //!< The weight of each sample in calculating the average, we arbitrarily average 10 samples for unlocked FPS
|
i64 sampleWeight{swapInterval ? constant::NsInSecond / (refreshCycleDuration * static_cast<i64>(swapInterval)) : 10}; //!< The weight of each sample in calculating the average, we arbitrarily average 10 samples for unlocked FPS
|
||||||
|
|
||||||
auto weightedAverage{[](auto weight, auto previousAverage, auto current) {
|
auto weightedAverage{[](auto weight, auto previousAverage, auto current) {
|
||||||
return (((weight - 1) * previousAverage) + current) / weight;
|
return (((weight - 1) * previousAverage) + current) / weight;
|
||||||
@ -314,7 +314,7 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
frameTimestamp = now;
|
frameTimestamp = now;
|
||||||
} else {
|
} else {
|
||||||
frameTimestamp = static_cast<i64>(util::GetTimeNs());
|
frameTimestamp = util::GetTimeNs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ namespace skyline::gpu {
|
|||||||
* @param frameId The ID of this frame for correlating it with presentation timing readouts
|
* @param frameId The ID of this frame for correlating it with presentation timing readouts
|
||||||
* @note The texture **must** be locked prior to calling this
|
* @note The texture **must** be locked prior to calling this
|
||||||
*/
|
*/
|
||||||
void Present(const std::shared_ptr<Texture> &texture, u64 timestamp, u64 swapInterval, service::hosbinder::AndroidRect crop, service::hosbinder::NativeWindowScalingMode scalingMode, service::hosbinder::NativeWindowTransform transform, u64 &frameId);
|
void Present(const std::shared_ptr<Texture> &texture, i64 timestamp, u64 swapInterval, service::hosbinder::AndroidRect crop, service::hosbinder::NativeWindowScalingMode scalingMode, service::hosbinder::NativeWindowTransform transform, u64 &frameId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A transform that the application should render with to elide costly transforms later
|
* @return A transform that the application should render with to elide costly transforms later
|
||||||
|
@ -50,15 +50,15 @@ namespace skyline::input {
|
|||||||
if (style.raw) {
|
if (style.raw) {
|
||||||
if (style.proController || style.joyconHandheld || style.joyconLeft || style.joyconRight) {
|
if (style.proController || style.joyconHandheld || style.joyconLeft || style.joyconRight) {
|
||||||
device.Connect(controller.type);
|
device.Connect(controller.type);
|
||||||
device.index = static_cast<size_t>(&controller - controllers.data());
|
device.index = static_cast<i8>(&controller - controllers.data());
|
||||||
device.partnerIndex = -1;
|
device.partnerIndex = -1;
|
||||||
controller.device = &device;
|
controller.device = &device;
|
||||||
} else if (style.joyconDual && orientation == NpadJoyOrientation::Vertical && device.GetAssignment() == NpadJoyAssignment::Dual) {
|
} else if (style.joyconDual && orientation == NpadJoyOrientation::Vertical && device.GetAssignment() == NpadJoyAssignment::Dual) {
|
||||||
device.Connect(NpadControllerType::JoyconDual);
|
device.Connect(NpadControllerType::JoyconDual);
|
||||||
device.index = static_cast<size_t>(&controller - controllers.data());
|
device.index = static_cast<i8>(&controller - controllers.data());
|
||||||
device.partnerIndex = controller.partnerIndex;
|
device.partnerIndex = controller.partnerIndex;
|
||||||
controller.device = &device;
|
controller.device = &device;
|
||||||
controllers.at(controller.partnerIndex).device = &device;
|
controllers.at(static_cast<size_t>(controller.partnerIndex)).device = &device;
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,10 @@ namespace skyline::input {
|
|||||||
jlong start;
|
jlong start;
|
||||||
jlong end;
|
jlong end;
|
||||||
|
|
||||||
VibrationInfo(float frequency, float amplitude) : period(MsInSecond / frequency), amplitude(amplitude), start(0), end(period) {}
|
VibrationInfo(float frequency, float amplitude)
|
||||||
|
: period(static_cast<jlong>(MsInSecond / frequency)),
|
||||||
|
amplitude(static_cast<jint>(amplitude)),
|
||||||
|
start(0), end(period) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t Size>
|
template<size_t Size>
|
||||||
|
@ -29,11 +29,11 @@ namespace skyline::input {
|
|||||||
for (size_t i{}; i < points.size(); i++) {
|
for (size_t i{}; i < points.size(); i++) {
|
||||||
const auto &host{points[i]};
|
const auto &host{points[i]};
|
||||||
auto &guest{entry.data[i]};
|
auto &guest{entry.data[i]};
|
||||||
guest.index = i;
|
guest.index = static_cast<u32>(i);
|
||||||
guest.positionX = host.x;
|
guest.positionX = static_cast<u32>(host.x);
|
||||||
guest.positionY = host.y;
|
guest.positionY = static_cast<u32>(host.y);
|
||||||
guest.minorAxis = host.minor;
|
guest.minorAxis = static_cast<u32>(host.minor);
|
||||||
guest.majorAxis = host.major;
|
guest.majorAxis = static_cast<u32>(host.major);
|
||||||
guest.angle = host.angle;
|
guest.angle = host.angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,10 +76,10 @@ namespace skyline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JvmManager::VibrateDevice(jint index, const span<jlong> &timings, const span<jint> &litudes) {
|
void JvmManager::VibrateDevice(jint index, const span<jlong> &timings, const span<jint> &litudes) {
|
||||||
auto jTimings{env->NewLongArray(timings.size())};
|
auto jTimings{env->NewLongArray(static_cast<jsize>(timings.size()))};
|
||||||
env->SetLongArrayRegion(jTimings, 0, timings.size(), timings.data());
|
env->SetLongArrayRegion(jTimings, 0, static_cast<jsize>(timings.size()), timings.data());
|
||||||
auto jAmplitudes{env->NewIntArray(amplitudes.size())};
|
auto jAmplitudes{env->NewIntArray(static_cast<jsize>(amplitudes.size()))};
|
||||||
env->SetIntArrayRegion(jAmplitudes, 0, amplitudes.size(), amplitudes.data());
|
env->SetIntArrayRegion(jAmplitudes, 0, static_cast<jsize>(amplitudes.size()), amplitudes.data());
|
||||||
|
|
||||||
env->CallVoidMethod(instance, vibrateDeviceId, index, jTimings, jAmplitudes);
|
env->CallVoidMethod(instance, vibrateDeviceId, index, jTimings, jAmplitudes);
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ namespace skyline {
|
|||||||
env->CallVoidMethod(instance, clearVibrationDeviceId, index);
|
env->CallVoidMethod(instance, clearVibrationDeviceId, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 JvmManager::GetVersionCode() {
|
i32 JvmManager::GetVersionCode() {
|
||||||
return env->CallIntMethod(instance, getVersionCodeId);
|
return env->CallIntMethod(instance, getVersionCodeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ namespace skyline {
|
|||||||
* @brief A call to EmulationActivity.getVersionCode in Kotlin
|
* @brief A call to EmulationActivity.getVersionCode in Kotlin
|
||||||
* @return A version code in Vulkan's format with 14-bit patch + 10-bit major and minor components
|
* @return A version code in Vulkan's format with 14-bit patch + 10-bit major and minor components
|
||||||
*/
|
*/
|
||||||
u32 GetVersionCode();
|
i32 GetVersionCode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
jmethodID initializeControllersId;
|
jmethodID initializeControllersId;
|
||||||
|
@ -64,7 +64,7 @@ namespace skyline::kernel::ipc {
|
|||||||
|
|
||||||
auto bufCPointer{pointer + header->rawSize * sizeof(u32)};
|
auto bufCPointer{pointer + header->rawSize * sizeof(u32)};
|
||||||
|
|
||||||
auto offset{pointer - tls}; // We calculate the relative offset as the absolute one might differ
|
size_t offset{static_cast<size_t>(pointer - tls)}; // We calculate the relative offset as the absolute one might differ
|
||||||
auto padding{util::AlignUp(offset, constant::IpcPaddingSum) - offset}; // Calculate the amount of padding at the front
|
auto padding{util::AlignUp(offset, constant::IpcPaddingSum) - offset}; // Calculate the amount of padding at the front
|
||||||
pointer += padding;
|
pointer += padding;
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ namespace skyline::kernel::ipc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto offset{pointer - tls}; // We calculate the relative offset as the absolute one might differ
|
size_t offset{static_cast<size_t>(pointer - tls)}; // We calculate the relative offset as the absolute one might differ
|
||||||
auto padding{util::AlignUp(offset, constant::IpcPaddingSum) - offset}; // Calculate the amount of padding at the front
|
auto padding{util::AlignUp(offset, constant::IpcPaddingSum) - offset}; // Calculate the amount of padding at the front
|
||||||
pointer += padding;
|
pointer += padding;
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ namespace skyline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u16 Counter() {
|
u16 Counter() {
|
||||||
return static_cast<u16>(counter0_5) | static_cast<u16>(counter9_11) << 9;
|
return static_cast<u16>(counter0_5) | static_cast<u16>(static_cast<u16>(counter9_11) << 9);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static_assert(sizeof(BufferDescriptorX) == 8);
|
static_assert(sizeof(BufferDescriptorX) == 8);
|
||||||
|
@ -146,7 +146,7 @@ namespace skyline::kernel {
|
|||||||
if (upper != chunks.end() && upper->ptr < chunk.ptr + chunk.size) {
|
if (upper != chunks.end() && upper->ptr < chunk.ptr + chunk.size) {
|
||||||
auto end{upper->ptr + upper->size};
|
auto end{upper->ptr + upper->size};
|
||||||
upper->ptr = chunk.ptr + chunk.size;
|
upper->ptr = chunk.ptr + chunk.size;
|
||||||
upper->size = end - upper->ptr;
|
upper->size = static_cast<size_t>(end - upper->ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lower{std::prev(upper)};
|
auto lower{std::prev(upper)};
|
||||||
@ -157,16 +157,16 @@ namespace skyline::kernel {
|
|||||||
} else if (lower->ptr + lower->size > chunk.ptr + chunk.size) {
|
} else if (lower->ptr + lower->size > chunk.ptr + chunk.size) {
|
||||||
auto lowerExtension{*lower};
|
auto lowerExtension{*lower};
|
||||||
lowerExtension.ptr = chunk.ptr + chunk.size;
|
lowerExtension.ptr = chunk.ptr + chunk.size;
|
||||||
lowerExtension.size = (lower->ptr + lower->size) - lowerExtension.ptr;
|
lowerExtension.size = static_cast<size_t>((lower->ptr + lower->size) - lowerExtension.ptr);
|
||||||
|
|
||||||
lower->size = chunk.ptr - lower->ptr;
|
lower->size = static_cast<size_t>(chunk.ptr - lower->ptr);
|
||||||
if (lower->size) {
|
if (lower->size) {
|
||||||
upper = chunks.insert(upper, lowerExtension);
|
upper = chunks.insert(upper, lowerExtension);
|
||||||
chunks.insert(upper, chunk);
|
chunks.insert(upper, chunk);
|
||||||
} else {
|
} else {
|
||||||
auto lower2{std::prev(lower)};
|
auto lower2{std::prev(lower)};
|
||||||
if (chunk.IsCompatible(*lower2) && lower2->ptr + lower2->size >= chunk.ptr) {
|
if (chunk.IsCompatible(*lower2) && lower2->ptr + lower2->size >= chunk.ptr) {
|
||||||
lower2->size = chunk.ptr + chunk.size - lower2->ptr;
|
lower2->size = static_cast<size_t>(chunk.ptr + chunk.size - lower2->ptr);
|
||||||
upper = chunks.erase(lower);
|
upper = chunks.erase(lower);
|
||||||
} else {
|
} else {
|
||||||
*lower = chunk;
|
*lower = chunk;
|
||||||
@ -174,10 +174,10 @@ namespace skyline::kernel {
|
|||||||
upper = chunks.insert(upper, lowerExtension);
|
upper = chunks.insert(upper, lowerExtension);
|
||||||
}
|
}
|
||||||
} else if (chunk.IsCompatible(*lower) && lower->ptr + lower->size >= chunk.ptr) {
|
} else if (chunk.IsCompatible(*lower) && lower->ptr + lower->size >= chunk.ptr) {
|
||||||
lower->size = chunk.ptr + chunk.size - lower->ptr;
|
lower->size = static_cast<size_t>(chunk.ptr + chunk.size - lower->ptr);
|
||||||
} else {
|
} else {
|
||||||
if (lower->ptr + lower->size > chunk.ptr)
|
if (lower->ptr + lower->size > chunk.ptr)
|
||||||
lower->size = chunk.ptr - lower->ptr;
|
lower->size = static_cast<size_t>(chunk.ptr - lower->ptr);
|
||||||
if (upper != chunks.end() && chunk.IsCompatible(*upper) && chunk.ptr + chunk.size >= upper->ptr) {
|
if (upper != chunks.end() && chunk.IsCompatible(*upper) && chunk.ptr + chunk.size >= upper->ptr) {
|
||||||
upper->ptr = chunk.ptr;
|
upper->ptr = chunk.ptr;
|
||||||
upper->size = chunk.size + upper->size;
|
upper->size = chunk.size + upper->size;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
|
|
||||||
namespace skyline::kernel {
|
namespace skyline::kernel {
|
||||||
Scheduler::CoreContext::CoreContext(u8 id, u8 preemptionPriority) : id(id), preemptionPriority(preemptionPriority) {}
|
Scheduler::CoreContext::CoreContext(u8 id, i8 preemptionPriority) : id(id), preemptionPriority(preemptionPriority) {}
|
||||||
|
|
||||||
Scheduler::Scheduler(const DeviceState &state) : state(state) {}
|
Scheduler::Scheduler(const DeviceState &state) : state(state) {}
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ namespace skyline {
|
|||||||
* @note Lower priority values result in a higher priority, similar to niceness on Linux
|
* @note Lower priority values result in a higher priority, similar to niceness on Linux
|
||||||
*/
|
*/
|
||||||
struct Priority {
|
struct Priority {
|
||||||
u8 min; //!< Numerically lowest priority, highest scheduler priority
|
i8 min; //!< Numerically lowest priority, highest scheduler priority
|
||||||
u8 max; //!< Numerically highest priority, lowest scheduler priority
|
i8 max; //!< Numerically highest priority, lowest scheduler priority
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A bitmask with each bit corresponding to if scheduler priority with the same index is valid
|
* @return A bitmask with each bit corresponding to if scheduler priority with the same index is valid
|
||||||
@ -30,7 +30,7 @@ namespace skyline {
|
|||||||
return (std::numeric_limits<u64>::max() >> ((std::numeric_limits<u64>::digits - 1 + min) - max)) << min;
|
return (std::numeric_limits<u64>::max() >> ((std::numeric_limits<u64>::digits - 1 + min) - max)) << min;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool Valid(u8 value) const {
|
constexpr bool Valid(i8 value) const {
|
||||||
return (value >= min) && (value <= max);
|
return (value >= min) && (value <= max);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -45,11 +45,11 @@ namespace skyline {
|
|||||||
|
|
||||||
struct CoreContext {
|
struct CoreContext {
|
||||||
u8 id;
|
u8 id;
|
||||||
u8 preemptionPriority; //!< The priority at which this core becomes preemptive as opposed to cooperative
|
i8 preemptionPriority; //!< The priority at which this core becomes preemptive as opposed to cooperative
|
||||||
std::mutex mutex; //!< Synchronizes all operations on the queue
|
std::mutex mutex; //!< Synchronizes all operations on the queue
|
||||||
std::list<std::shared_ptr<type::KThread>> queue; //!< A queue of threads which are running or to be run on this core
|
std::list<std::shared_ptr<type::KThread>> queue; //!< A queue of threads which are running or to be run on this core
|
||||||
|
|
||||||
CoreContext(u8 id, u8 preemptionPriority);
|
CoreContext(u8 id, i8 preemptionPriority);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::array<CoreContext, constant::CoreCount> cores{CoreContext(0, 59), CoreContext(1, 59), CoreContext(2, 59), CoreContext(3, 63)};
|
std::array<CoreContext, constant::CoreCount> cores{CoreContext(0, 59), CoreContext(1, 59), CoreContext(2, 59), CoreContext(3, 63)};
|
||||||
|
@ -230,10 +230,10 @@ namespace skyline::kernel::svc {
|
|||||||
auto entry{reinterpret_cast<void *>(state.ctx->gpr.x1)};
|
auto entry{reinterpret_cast<void *>(state.ctx->gpr.x1)};
|
||||||
auto entryArgument{state.ctx->gpr.x2};
|
auto entryArgument{state.ctx->gpr.x2};
|
||||||
auto stackTop{reinterpret_cast<u8 *>(state.ctx->gpr.x3)};
|
auto stackTop{reinterpret_cast<u8 *>(state.ctx->gpr.x3)};
|
||||||
auto priority{static_cast<i8>(static_cast<u32>(state.ctx->gpr.w4))};
|
auto priority{static_cast<i8>(state.ctx->gpr.w4)};
|
||||||
auto idealCore{static_cast<i8>(static_cast<u32>(state.ctx->gpr.w5))};
|
auto idealCore{static_cast<i32>(state.ctx->gpr.w5)};
|
||||||
|
|
||||||
idealCore = (idealCore == IdealCoreUseProcessValue) ? state.process->npdm.meta.idealCore : idealCore;
|
idealCore = (idealCore == IdealCoreUseProcessValue) ? static_cast<i32>(state.process->npdm.meta.idealCore) : idealCore;
|
||||||
if (idealCore < 0 || idealCore >= constant::CoreCount) {
|
if (idealCore < 0 || idealCore >= constant::CoreCount) {
|
||||||
state.ctx->gpr.w0 = result::InvalidCoreId;
|
state.ctx->gpr.w0 = result::InvalidCoreId;
|
||||||
state.logger->Warn("'idealCore' invalid: {}", idealCore);
|
state.logger->Warn("'idealCore' invalid: {}", idealCore);
|
||||||
@ -250,7 +250,7 @@ namespace skyline::kernel::svc {
|
|||||||
if (!stack)
|
if (!stack)
|
||||||
throw exception("svcCreateThread: Cannot find memory object in handle table for thread stack: 0x{:X}", stackTop);
|
throw exception("svcCreateThread: Cannot find memory object in handle table for thread stack: 0x{:X}", stackTop);
|
||||||
|
|
||||||
auto thread{state.process->CreateThread(entry, entryArgument, stackTop, priority, idealCore)};
|
auto thread{state.process->CreateThread(entry, entryArgument, stackTop, priority, static_cast<u8>(idealCore))};
|
||||||
if (thread) {
|
if (thread) {
|
||||||
state.logger->Debug("Created thread #{} with handle 0x{:X} (Entry Point: 0x{:X}, Argument: 0x{:X}, Stack Pointer: 0x{:X}, Priority: {}, Ideal Core: {})", thread->id, thread->handle, entry, entryArgument, stackTop, priority, idealCore);
|
state.logger->Debug("Created thread #{} with handle 0x{:X} (Entry Point: 0x{:X}, Argument: 0x{:X}, Stack Pointer: 0x{:X}, Priority: {}, Ideal Core: {})", thread->id, thread->handle, entry, entryArgument, stackTop, priority, idealCore);
|
||||||
|
|
||||||
@ -335,10 +335,10 @@ namespace skyline::kernel::svc {
|
|||||||
KHandle handle{state.ctx->gpr.w1};
|
KHandle handle{state.ctx->gpr.w1};
|
||||||
try {
|
try {
|
||||||
auto thread{state.process->GetHandle<type::KThread>(handle)};
|
auto thread{state.process->GetHandle<type::KThread>(handle)};
|
||||||
u8 priority{thread->priority};
|
i8 priority{thread->priority};
|
||||||
state.logger->Debug("Retrieving thread #{}'s priority: {}", thread->id, priority);
|
state.logger->Debug("Retrieving thread #{}'s priority: {}", thread->id, priority);
|
||||||
|
|
||||||
state.ctx->gpr.w1 = priority;
|
state.ctx->gpr.w1 = static_cast<u32>(priority);
|
||||||
state.ctx->gpr.w0 = Result{};
|
state.ctx->gpr.w0 = Result{};
|
||||||
} catch (const std::out_of_range &) {
|
} catch (const std::out_of_range &) {
|
||||||
state.logger->Warn("'handle' invalid: 0x{:X}", handle);
|
state.logger->Warn("'handle' invalid: 0x{:X}", handle);
|
||||||
@ -348,7 +348,7 @@ namespace skyline::kernel::svc {
|
|||||||
|
|
||||||
void SetThreadPriority(const DeviceState &state) {
|
void SetThreadPriority(const DeviceState &state) {
|
||||||
KHandle handle{state.ctx->gpr.w0};
|
KHandle handle{state.ctx->gpr.w0};
|
||||||
u8 priority{static_cast<u8>(state.ctx->gpr.w1)};
|
i8 priority{static_cast<i8>(state.ctx->gpr.w1)};
|
||||||
if (!state.process->npdm.threadInfo.priority.Valid(priority)) {
|
if (!state.process->npdm.threadInfo.priority.Valid(priority)) {
|
||||||
state.logger->Warn("'priority' invalid: 0x{:X}", priority);
|
state.logger->Warn("'priority' invalid: 0x{:X}", priority);
|
||||||
state.ctx->gpr.w0 = result::InvalidPriority;
|
state.ctx->gpr.w0 = result::InvalidPriority;
|
||||||
@ -359,7 +359,7 @@ namespace skyline::kernel::svc {
|
|||||||
state.logger->Debug("Setting thread #{}'s priority to {}", thread->id, priority);
|
state.logger->Debug("Setting thread #{}'s priority to {}", thread->id, priority);
|
||||||
if (thread->priority != priority) {
|
if (thread->priority != priority) {
|
||||||
thread->basePriority = priority;
|
thread->basePriority = priority;
|
||||||
u8 newPriority{};
|
i8 newPriority{};
|
||||||
do {
|
do {
|
||||||
// Try to CAS the priority of the thread with its new base priority
|
// Try to CAS the priority of the thread with its new base priority
|
||||||
// If the new priority is equivalent to the current priority then we don't need to CAS
|
// If the new priority is equivalent to the current priority then we don't need to CAS
|
||||||
@ -385,7 +385,7 @@ namespace skyline::kernel::svc {
|
|||||||
state.logger->Debug("Getting thread #{}'s Ideal Core ({}) + Affinity Mask ({})", thread->id, idealCore, affinityMask);
|
state.logger->Debug("Getting thread #{}'s Ideal Core ({}) + Affinity Mask ({})", thread->id, idealCore, affinityMask);
|
||||||
|
|
||||||
state.ctx->gpr.x2 = affinityMask.to_ullong();
|
state.ctx->gpr.x2 = affinityMask.to_ullong();
|
||||||
state.ctx->gpr.w1 = idealCore;
|
state.ctx->gpr.w1 = static_cast<u32>(idealCore);
|
||||||
state.ctx->gpr.w0 = Result{};
|
state.ctx->gpr.w0 = Result{};
|
||||||
} catch (const std::out_of_range &) {
|
} catch (const std::out_of_range &) {
|
||||||
state.logger->Warn("'handle' invalid: 0x{:X}", handle);
|
state.logger->Warn("'handle' invalid: 0x{:X}", handle);
|
||||||
@ -402,7 +402,7 @@ namespace skyline::kernel::svc {
|
|||||||
|
|
||||||
if (idealCore == IdealCoreUseProcessValue) {
|
if (idealCore == IdealCoreUseProcessValue) {
|
||||||
idealCore = state.process->npdm.meta.idealCore;
|
idealCore = state.process->npdm.meta.idealCore;
|
||||||
affinityMask.reset().set(idealCore);
|
affinityMask.reset().set(static_cast<size_t>(idealCore));
|
||||||
} else if (idealCore == IdealCoreNoUpdate) {
|
} else if (idealCore == IdealCoreNoUpdate) {
|
||||||
idealCore = thread->idealCore;
|
idealCore = thread->idealCore;
|
||||||
} else if (idealCore == IdealCoreDontCare) {
|
} else if (idealCore == IdealCoreDontCare) {
|
||||||
@ -416,7 +416,7 @@ namespace skyline::kernel::svc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (affinityMask.none() || !affinityMask.test(idealCore)) {
|
if (affinityMask.none() || !affinityMask.test(static_cast<size_t>(idealCore))) {
|
||||||
state.logger->Warn("'affinityMask' invalid: {} (Ideal Core: {})", affinityMask, idealCore);
|
state.logger->Warn("'affinityMask' invalid: {} (Ideal Core: {})", affinityMask, idealCore);
|
||||||
state.ctx->gpr.w0 = result::InvalidCombination;
|
state.ctx->gpr.w0 = result::InvalidCombination;
|
||||||
return;
|
return;
|
||||||
@ -425,19 +425,19 @@ namespace skyline::kernel::svc {
|
|||||||
state.logger->Debug("Setting thread #{}'s Ideal Core ({}) + Affinity Mask ({})", thread->id, idealCore, affinityMask);
|
state.logger->Debug("Setting thread #{}'s Ideal Core ({}) + Affinity Mask ({})", thread->id, idealCore, affinityMask);
|
||||||
|
|
||||||
std::lock_guard guard(thread->coreMigrationMutex);
|
std::lock_guard guard(thread->coreMigrationMutex);
|
||||||
thread->idealCore = idealCore;
|
thread->idealCore = static_cast<u8>(idealCore);
|
||||||
thread->affinityMask = affinityMask;
|
thread->affinityMask = affinityMask;
|
||||||
|
|
||||||
if (!affinityMask.test(thread->coreId) && thread->coreId != constant::ParkedCoreId) {
|
if (!affinityMask.test(static_cast<size_t>(thread->coreId)) && thread->coreId != constant::ParkedCoreId) {
|
||||||
state.logger->Debug("Migrating thread #{} to Ideal Core C{} -> C{}", thread->id, thread->coreId, idealCore);
|
state.logger->Debug("Migrating thread #{} to Ideal Core C{} -> C{}", thread->id, thread->coreId, idealCore);
|
||||||
|
|
||||||
if (thread == state.thread) {
|
if (thread == state.thread) {
|
||||||
state.scheduler->RemoveThread();
|
state.scheduler->RemoveThread();
|
||||||
thread->coreId = idealCore;
|
thread->coreId = static_cast<u8>(idealCore);
|
||||||
state.scheduler->InsertThread(state.thread);
|
state.scheduler->InsertThread(state.thread);
|
||||||
state.scheduler->WaitSchedule();
|
state.scheduler->WaitSchedule();
|
||||||
} else if (!thread->running) {
|
} else if (!thread->running) {
|
||||||
thread->coreId = idealCore;
|
thread->coreId = static_cast<u8>(idealCore);
|
||||||
} else {
|
} else {
|
||||||
state.scheduler->UpdateCore(thread);
|
state.scheduler->UpdateCore(thread);
|
||||||
}
|
}
|
||||||
@ -452,7 +452,7 @@ namespace skyline::kernel::svc {
|
|||||||
|
|
||||||
void GetCurrentProcessorNumber(const DeviceState &state) {
|
void GetCurrentProcessorNumber(const DeviceState &state) {
|
||||||
std::lock_guard guard(state.thread->coreMigrationMutex);
|
std::lock_guard guard(state.thread->coreMigrationMutex);
|
||||||
auto coreId{state.thread->coreId};
|
u8 coreId{state.thread->coreId};
|
||||||
state.logger->Debug("C{}", coreId);
|
state.logger->Debug("C{}", coreId);
|
||||||
state.ctx->gpr.w0 = coreId;
|
state.ctx->gpr.w0 = coreId;
|
||||||
}
|
}
|
||||||
@ -490,7 +490,7 @@ namespace skyline::kernel::svc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory::Permission permission(state.ctx->gpr.w3);
|
memory::Permission permission(static_cast<u8>(state.ctx->gpr.w3));
|
||||||
if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
|
if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
|
||||||
state.logger->Warn("'permission' invalid: {}{}{}", permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-');
|
state.logger->Warn("'permission' invalid: {}{}{}", permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-');
|
||||||
state.ctx->gpr.w0 = result::InvalidNewMemoryPermission;
|
state.ctx->gpr.w0 = result::InvalidNewMemoryPermission;
|
||||||
@ -553,7 +553,7 @@ namespace skyline::kernel::svc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory::Permission permission(state.ctx->gpr.w3);
|
memory::Permission permission(static_cast<u8>(state.ctx->gpr.w3));
|
||||||
if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
|
if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
|
||||||
state.logger->Warn("'permission' invalid: {}{}{}", permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-');
|
state.logger->Warn("'permission' invalid: {}{}{}", permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-');
|
||||||
state.ctx->gpr.w0 = result::InvalidNewMemoryPermission;
|
state.ctx->gpr.w0 = result::InvalidNewMemoryPermission;
|
||||||
@ -1067,10 +1067,10 @@ namespace skyline::kernel::svc {
|
|||||||
item->Resize(0);
|
item->Resize(0);
|
||||||
state.process->CloseHandle(memory->handle);
|
state.process->CloseHandle(memory->handle);
|
||||||
} else {
|
} else {
|
||||||
item->Remap(pointer + size, item->size - (size + (item->ptr - pointer)));
|
item->Remap(pointer + size, item->size - (size + static_cast<size_t>(item->ptr - pointer)));
|
||||||
}
|
}
|
||||||
} else if (item->ptr < pointer) {
|
} else if (item->ptr < pointer) {
|
||||||
item->Resize(pointer - item->ptr);
|
item->Resize(static_cast<size_t>(pointer - item->ptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pointer += initialSize;
|
pointer += initialSize;
|
||||||
|
@ -57,7 +57,7 @@ namespace skyline::kernel::type {
|
|||||||
return tlsPage->ReserveSlot();
|
return tlsPage->ReserveSlot();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<KThread> KProcess::CreateThread(void *entry, u64 argument, void *stackTop, std::optional<u8> priority, std::optional<u8> idealCore) {
|
std::shared_ptr<KThread> KProcess::CreateThread(void *entry, u64 argument, void *stackTop, std::optional<i8> priority, std::optional<u8> idealCore) {
|
||||||
std::lock_guard guard(threadMutex);
|
std::lock_guard guard(threadMutex);
|
||||||
if (disableThreadCreation)
|
if (disableThreadCreation)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -172,14 +172,14 @@ namespace skyline::kernel::type {
|
|||||||
if (!waiters.empty()) {
|
if (!waiters.empty()) {
|
||||||
// If there are threads still waiting on us then try to inherit their priority
|
// If there are threads still waiting on us then try to inherit their priority
|
||||||
auto highestPriorityThread{waiters.front()};
|
auto highestPriorityThread{waiters.front()};
|
||||||
u8 newPriority, basePriority;
|
i8 newPriority, basePriority;
|
||||||
do {
|
do {
|
||||||
basePriority = state.thread->basePriority.load();
|
basePriority = state.thread->basePriority.load();
|
||||||
newPriority = std::min(basePriority, highestPriorityThread->priority.load());
|
newPriority = std::min(basePriority, highestPriorityThread->priority.load());
|
||||||
} while (basePriority != newPriority && state.thread->priority.compare_exchange_strong(basePriority, newPriority));
|
} while (basePriority != newPriority && state.thread->priority.compare_exchange_strong(basePriority, newPriority));
|
||||||
state.scheduler->UpdatePriority(state.thread);
|
state.scheduler->UpdatePriority(state.thread);
|
||||||
} else {
|
} else {
|
||||||
u8 priority, basePriority;
|
i8 priority, basePriority;
|
||||||
do {
|
do {
|
||||||
basePriority = state.thread->basePriority.load();
|
basePriority = state.thread->basePriority.load();
|
||||||
priority = state.thread->priority.load();
|
priority = state.thread->priority.load();
|
||||||
@ -190,7 +190,7 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
if (nextWaiter) {
|
if (nextWaiter) {
|
||||||
// If there is a waiter on the new owner then try to inherit its priority
|
// If there is a waiter on the new owner then try to inherit its priority
|
||||||
u8 priority, ownerPriority;
|
i8 priority, ownerPriority;
|
||||||
do {
|
do {
|
||||||
ownerPriority = nextOwner->priority.load();
|
ownerPriority = nextOwner->priority.load();
|
||||||
priority = std::min(ownerPriority, nextWaiter->priority.load());
|
priority = std::min(ownerPriority, nextWaiter->priority.load());
|
||||||
|
@ -94,7 +94,7 @@ namespace skyline {
|
|||||||
* @return A shared pointer to a KThread initialized with the specified values or nullptr, if thread creation has been disabled
|
* @return A shared pointer to a KThread initialized with the specified values or nullptr, if thread creation has been disabled
|
||||||
* @note The default values are for the main thread and will use values from the NPDM
|
* @note The default values are for the main thread and will use values from the NPDM
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<KThread> CreateThread(void *entry, u64 argument = 0, void *stackTop = nullptr, std::optional<u8> priority = std::nullopt, std::optional<u8> idealCore = std::nullopt);
|
std::shared_ptr<KThread> CreateThread(void *entry, u64 argument = 0, void *stackTop = nullptr, std::optional<i8> priority = std::nullopt, std::optional<u8> idealCore = std::nullopt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The output for functions that return created kernel objects
|
* @brief The output for functions that return created kernel objects
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include "KThread.h"
|
#include "KThread.h"
|
||||||
|
|
||||||
namespace skyline::kernel::type {
|
namespace skyline::kernel::type {
|
||||||
KThread::KThread(const DeviceState &state, KHandle handle, KProcess *parent, size_t id, void *entry, u64 argument, void *stackTop, u8 priority, i8 idealCore) : handle(handle), parent(parent), id(id), entry(entry), entryArgument(argument), stackTop(stackTop), priority(priority), basePriority(priority), idealCore(idealCore), coreId(idealCore), KSyncObject(state, KType::KThread) {
|
KThread::KThread(const DeviceState &state, KHandle handle, KProcess *parent, size_t id, void *entry, u64 argument, void *stackTop, i8 priority, u8 idealCore) : handle(handle), parent(parent), id(id), entry(entry), entryArgument(argument), stackTop(stackTop), priority(priority), basePriority(priority), idealCore(idealCore), coreId(idealCore), KSyncObject(state, KType::KThread) {
|
||||||
affinityMask.set(coreId);
|
affinityMask.set(coreId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ namespace skyline::kernel::type {
|
|||||||
statusCondition.wait(lock, [this]() { return ready || killed; });
|
statusCondition.wait(lock, [this]() { return ready || killed; });
|
||||||
if (!killed && running) {
|
if (!killed && running) {
|
||||||
struct itimerspec spec{.it_value = {
|
struct itimerspec spec{.it_value = {
|
||||||
.tv_nsec = std::min(timeToFire.count(), static_cast<long long>(constant::NsInSecond)),
|
.tv_nsec = std::min(static_cast<i64>(timeToFire.count()), constant::NsInSecond),
|
||||||
.tv_sec = std::max(std::chrono::duration_cast<std::chrono::seconds>(timeToFire).count() - 1, 0LL),
|
.tv_sec = std::max(std::chrono::duration_cast<std::chrono::seconds>(timeToFire).count() - 1, 0LL),
|
||||||
}};
|
}};
|
||||||
timer_settime(preemptionTimer, 0, &spec, nullptr);
|
timer_settime(preemptionTimer, 0, &spec, nullptr);
|
||||||
@ -258,9 +258,9 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
void KThread::UpdatePriorityInheritance() {
|
void KThread::UpdatePriorityInheritance() {
|
||||||
auto waitingOn{waitThread};
|
auto waitingOn{waitThread};
|
||||||
u8 currentPriority{priority.load()};
|
i8 currentPriority{priority.load()};
|
||||||
while (waitingOn) {
|
while (waitingOn) {
|
||||||
u8 ownerPriority;
|
i8 ownerPriority;
|
||||||
do {
|
do {
|
||||||
// Try to CAS the priority of the owner with the current thread
|
// Try to CAS the priority of the owner with the current thread
|
||||||
// If the new priority is equivalent to the current priority then we don't need to CAS
|
// If the new priority is equivalent to the current priority then we don't need to CAS
|
||||||
|
@ -47,12 +47,12 @@ namespace skyline {
|
|||||||
void *stackTop; //!< The top of the guest's stack, this is set to the initial guest stack pointer
|
void *stackTop; //!< The top of the guest's stack, this is set to the initial guest stack pointer
|
||||||
|
|
||||||
std::condition_variable scheduleCondition; //!< Signalled to wake the thread when it's scheduled or its resident core changes
|
std::condition_variable scheduleCondition; //!< Signalled to wake the thread when it's scheduled or its resident core changes
|
||||||
std::atomic<u8> basePriority; //!< The priority of the thread for the scheduler without any priority-inheritance
|
std::atomic<i8> basePriority; //!< The priority of the thread for the scheduler without any priority-inheritance
|
||||||
std::atomic<u8> priority; //!< The priority of the thread for the scheduler including priority-inheritance
|
std::atomic<i8> priority; //!< The priority of the thread for the scheduler including priority-inheritance
|
||||||
|
|
||||||
std::mutex coreMigrationMutex; //!< Synchronizes operations which depend on which core the thread is running on
|
std::mutex coreMigrationMutex; //!< Synchronizes operations which depend on which core the thread is running on
|
||||||
i8 idealCore; //!< The ideal CPU core for this thread to run on
|
u8 idealCore; //!< The ideal CPU core for this thread to run on
|
||||||
i8 coreId; //!< The CPU core on which this thread is running
|
u8 coreId; //!< The CPU core on which this thread is running
|
||||||
CoreMask affinityMask{}; //!< A mask of CPU cores this thread is allowed to run on
|
CoreMask affinityMask{}; //!< A mask of CPU cores this thread is allowed to run on
|
||||||
|
|
||||||
u64 timesliceStart{}; //!< A timestamp in host CNTVCT ticks of when the thread's current timeslice started
|
u64 timesliceStart{}; //!< A timestamp in host CNTVCT ticks of when the thread's current timeslice started
|
||||||
@ -72,7 +72,7 @@ namespace skyline {
|
|||||||
bool cancelSync{false}; //!< Whether to cancel the SvcWaitSynchronization call this thread currently is in/the next one it joins
|
bool cancelSync{false}; //!< Whether to cancel the SvcWaitSynchronization call this thread currently is in/the next one it joins
|
||||||
type::KSyncObject *wakeObject{}; //!< A pointer to the synchronization object responsible for waking this thread up
|
type::KSyncObject *wakeObject{}; //!< A pointer to the synchronization object responsible for waking this thread up
|
||||||
|
|
||||||
KThread(const DeviceState &state, KHandle handle, KProcess *parent, size_t id, void *entry, u64 argument, void *stackTop, u8 priority, i8 idealCore);
|
KThread(const DeviceState &state, KHandle handle, KProcess *parent, size_t id, void *entry, u64 argument, void *stackTop, i8 priority, u8 idealCore);
|
||||||
|
|
||||||
~KThread();
|
~KThread();
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ namespace skyline::loader {
|
|||||||
std::vector<u8> compressedBuffer(compressedSize);
|
std::vector<u8> compressedBuffer(compressedSize);
|
||||||
backing->Read(compressedBuffer, segment.fileOffset);
|
backing->Read(compressedBuffer, segment.fileOffset);
|
||||||
|
|
||||||
LZ4_decompress_safe(reinterpret_cast<char *>(compressedBuffer.data()), reinterpret_cast<char *>(outputBuffer.data()), compressedSize, segment.decompressedSize);
|
LZ4_decompress_safe(reinterpret_cast<char *>(compressedBuffer.data()), reinterpret_cast<char *>(outputBuffer.data()), static_cast<int>(compressedSize), static_cast<int>(segment.decompressedSize));
|
||||||
} else {
|
} else {
|
||||||
backing->Read(outputBuffer, segment.fileOffset);
|
backing->Read(outputBuffer, segment.fileOffset);
|
||||||
}
|
}
|
||||||
|
@ -166,30 +166,31 @@ namespace skyline::nce {
|
|||||||
auto svc{*reinterpret_cast<const instructions::Svc *>(instruction)};
|
auto svc{*reinterpret_cast<const instructions::Svc *>(instruction)};
|
||||||
auto mrs{*reinterpret_cast<const instructions::Mrs *>(instruction)};
|
auto mrs{*reinterpret_cast<const instructions::Mrs *>(instruction)};
|
||||||
auto msr{*reinterpret_cast<const instructions::Msr *>(instruction)};
|
auto msr{*reinterpret_cast<const instructions::Msr *>(instruction)};
|
||||||
|
auto instructionOffset{static_cast<size_t>(instruction - start)};
|
||||||
|
|
||||||
if (svc.Verify()) {
|
if (svc.Verify()) {
|
||||||
size += 7;
|
size += 7;
|
||||||
offsets.push_back(instruction - start);
|
offsets.push_back(instructionOffset);
|
||||||
} else if (mrs.Verify()) {
|
} else if (mrs.Verify()) {
|
||||||
if (mrs.srcReg == TpidrroEl0 || mrs.srcReg == TpidrEl0) {
|
if (mrs.srcReg == TpidrroEl0 || mrs.srcReg == TpidrEl0) {
|
||||||
size += ((mrs.destReg != registers::X0) ? 6 : 3);
|
size += ((mrs.destReg != registers::X0) ? 6 : 3);
|
||||||
offsets.push_back(instruction - start);
|
offsets.push_back(instructionOffset);
|
||||||
} else {
|
} else {
|
||||||
if (rescaleClock) {
|
if (rescaleClock) {
|
||||||
if (mrs.srcReg == CntpctEl0) {
|
if (mrs.srcReg == CntpctEl0) {
|
||||||
size += guest::RescaleClockSize + 3;
|
size += guest::RescaleClockSize + 3;
|
||||||
offsets.push_back(instruction - start);
|
offsets.push_back(instructionOffset);
|
||||||
} else if (mrs.srcReg == CntfrqEl0) {
|
} else if (mrs.srcReg == CntfrqEl0) {
|
||||||
size += 3;
|
size += 3;
|
||||||
offsets.push_back(instruction - start);
|
offsets.push_back(instructionOffset);
|
||||||
}
|
}
|
||||||
} else if (mrs.srcReg == CntpctEl0) {
|
} else if (mrs.srcReg == CntpctEl0) {
|
||||||
offsets.push_back(instruction - start);
|
offsets.push_back(instructionOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (msr.Verify() && msr.destReg == TpidrEl0) {
|
} else if (msr.Verify() && msr.destReg == TpidrEl0) {
|
||||||
size += 6;
|
size += 6;
|
||||||
offsets.push_back(instruction - start);
|
offsets.push_back(instructionOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {util::AlignUp(size * sizeof(u32), PAGE_SIZE), offsets};
|
return {util::AlignUp(size * sizeof(u32), PAGE_SIZE), offsets};
|
||||||
@ -248,33 +249,35 @@ namespace skyline::nce {
|
|||||||
auto svc{*reinterpret_cast<instructions::Svc *>(instruction)};
|
auto svc{*reinterpret_cast<instructions::Svc *>(instruction)};
|
||||||
auto mrs{*reinterpret_cast<instructions::Mrs *>(instruction)};
|
auto mrs{*reinterpret_cast<instructions::Mrs *>(instruction)};
|
||||||
auto msr{*reinterpret_cast<instructions::Msr *>(instruction)};
|
auto msr{*reinterpret_cast<instructions::Msr *>(instruction)};
|
||||||
|
auto endOffset{[&] { return static_cast<size_t>(end - patch); }};
|
||||||
|
auto startOffset{[&] { return static_cast<size_t>(start - patch); }};
|
||||||
|
|
||||||
if (svc.Verify()) {
|
if (svc.Verify()) {
|
||||||
/* Per-SVC Trampoline */
|
/* Per-SVC Trampoline */
|
||||||
/* Rewrite SVC with B to trampoline */
|
/* Rewrite SVC with B to trampoline */
|
||||||
*instruction = instructions::B((end - patch) + offset, true).raw;
|
*instruction = instructions::B(static_cast<i32>(endOffset() + offset), true).raw;
|
||||||
|
|
||||||
/* Save Context */
|
/* Save Context */
|
||||||
*patch++ = 0xF81F0FFE; // STR LR, [SP, #-16]!
|
*patch++ = 0xF81F0FFE; // STR LR, [SP, #-16]!
|
||||||
*patch = instructions::BL(start - patch).raw;
|
*patch = instructions::BL(static_cast<i32>(startOffset())).raw;
|
||||||
patch++;
|
patch++;
|
||||||
|
|
||||||
/* Jump to main SVC trampoline */
|
/* Jump to main SVC trampoline */
|
||||||
*patch++ = instructions::Movz(registers::W0, static_cast<u16>(svc.value)).raw;
|
*patch++ = instructions::Movz(registers::W0, static_cast<u16>(svc.value)).raw;
|
||||||
*patch = instructions::BL((start - patch) + guest::SaveCtxSize).raw;
|
*patch = instructions::BL(static_cast<i32>(startOffset() + guest::SaveCtxSize)).raw;
|
||||||
patch++;
|
patch++;
|
||||||
|
|
||||||
/* Restore Context and Return */
|
/* Restore Context and Return */
|
||||||
*patch = instructions::BL((start - patch) + guest::SaveCtxSize + MainSvcTrampolineSize).raw;
|
*patch = instructions::BL(static_cast<i32>(startOffset() + guest::SaveCtxSize + MainSvcTrampolineSize)).raw;
|
||||||
patch++;
|
patch++;
|
||||||
*patch++ = 0xF84107FE; // LDR LR, [SP], #16
|
*patch++ = 0xF84107FE; // LDR LR, [SP], #16
|
||||||
*patch = instructions::B((end - patch) + offset + 1).raw;
|
*patch = instructions::B(static_cast<i32>(endOffset() + offset + 1)).raw;
|
||||||
patch++;
|
patch++;
|
||||||
} else if (mrs.Verify()) {
|
} else if (mrs.Verify()) {
|
||||||
if (mrs.srcReg == TpidrroEl0 || mrs.srcReg == TpidrEl0) {
|
if (mrs.srcReg == TpidrroEl0 || mrs.srcReg == TpidrEl0) {
|
||||||
/* Emulated TLS Register Load */
|
/* Emulated TLS Register Load */
|
||||||
/* Rewrite MRS with B to trampoline */
|
/* Rewrite MRS with B to trampoline */
|
||||||
*instruction = instructions::B((end - patch) + offset, true).raw;
|
*instruction = instructions::B(static_cast<i32>(endOffset() + offset), true).raw;
|
||||||
|
|
||||||
/* Allocate Scratch Register */
|
/* Allocate Scratch Register */
|
||||||
if (mrs.destReg != registers::X0)
|
if (mrs.destReg != registers::X0)
|
||||||
@ -292,14 +295,14 @@ namespace skyline::nce {
|
|||||||
*patch++ = instructions::Mov(registers::X(mrs.destReg), registers::X0).raw;
|
*patch++ = instructions::Mov(registers::X(mrs.destReg), registers::X0).raw;
|
||||||
*patch++ = 0xF84107E0; // LDR X0, [SP], #16
|
*patch++ = 0xF84107E0; // LDR X0, [SP], #16
|
||||||
}
|
}
|
||||||
*patch = instructions::B((end - patch) + offset + 1).raw;
|
*patch = instructions::B(static_cast<i32>(endOffset() + offset + 1)).raw;
|
||||||
patch++;
|
patch++;
|
||||||
} else {
|
} else {
|
||||||
if (rescaleClock) {
|
if (rescaleClock) {
|
||||||
if (mrs.srcReg == CntpctEl0) {
|
if (mrs.srcReg == CntpctEl0) {
|
||||||
/* Physical Counter Load Emulation (With Rescaling) */
|
/* Physical Counter Load Emulation (With Rescaling) */
|
||||||
/* Rewrite MRS with B to trampoline */
|
/* Rewrite MRS with B to trampoline */
|
||||||
*instruction = instructions::B((end - patch) + offset, true).raw;
|
*instruction = instructions::B(static_cast<i32>(endOffset() + offset), true).raw;
|
||||||
|
|
||||||
/* Rescale host clock */
|
/* Rescale host clock */
|
||||||
std::memcpy(patch, reinterpret_cast<void *>(&guest::RescaleClock), guest::RescaleClockSize * sizeof(u32));
|
std::memcpy(patch, reinterpret_cast<void *>(&guest::RescaleClock), guest::RescaleClockSize * sizeof(u32));
|
||||||
@ -312,17 +315,17 @@ namespace skyline::nce {
|
|||||||
|
|
||||||
/* Free 32B stack allocation by RescaleClock and Return */
|
/* Free 32B stack allocation by RescaleClock and Return */
|
||||||
*patch++ = {0x910083FF}; // ADD SP, SP, #32
|
*patch++ = {0x910083FF}; // ADD SP, SP, #32
|
||||||
*patch = instructions::B((end - patch) + offset + 1).raw;
|
*patch = instructions::B(static_cast<i32>(endOffset() + offset + 1)).raw;
|
||||||
patch++;
|
patch++;
|
||||||
} else if (mrs.srcReg == CntfrqEl0) {
|
} else if (mrs.srcReg == CntfrqEl0) {
|
||||||
/* Physical Counter Frequency Load Emulation */
|
/* Physical Counter Frequency Load Emulation */
|
||||||
/* Rewrite MRS with B to trampoline */
|
/* Rewrite MRS with B to trampoline */
|
||||||
*instruction = instructions::B((end - patch) + offset, true).raw;
|
*instruction = instructions::B(static_cast<i32>(endOffset() + offset), true).raw;
|
||||||
|
|
||||||
/* Write back Tegra X1 Counter Frequency and Return */
|
/* Write back Tegra X1 Counter Frequency and Return */
|
||||||
for (const auto &mov : instructions::MoveRegister(registers::X(mrs.destReg), TegraX1Freq))
|
for (const auto &mov : instructions::MoveRegister(registers::X(mrs.destReg), TegraX1Freq))
|
||||||
*patch++ = mov;
|
*patch++ = mov;
|
||||||
*patch = instructions::B((end - patch) + offset + 1).raw;
|
*patch = instructions::B(static_cast<i32>(endOffset() + offset + 1)).raw;
|
||||||
patch++;
|
patch++;
|
||||||
}
|
}
|
||||||
} else if (mrs.srcReg == CntpctEl0) {
|
} else if (mrs.srcReg == CntpctEl0) {
|
||||||
@ -334,7 +337,7 @@ namespace skyline::nce {
|
|||||||
} else if (msr.Verify() && msr.destReg == TpidrEl0) {
|
} else if (msr.Verify() && msr.destReg == TpidrEl0) {
|
||||||
/* Emulated TLS Register Store */
|
/* Emulated TLS Register Store */
|
||||||
/* Rewrite MSR with B to trampoline */
|
/* Rewrite MSR with B to trampoline */
|
||||||
*instruction = instructions::B((end - patch) + offset, true).raw;
|
*instruction = instructions::B(static_cast<i32>(endOffset() + offset), true).raw;
|
||||||
|
|
||||||
/* Allocate Scratch Registers */
|
/* Allocate Scratch Registers */
|
||||||
bool x0x1{mrs.srcReg != registers::X0 && mrs.srcReg != registers::X1};
|
bool x0x1{mrs.srcReg != registers::X0 && mrs.srcReg != registers::X1};
|
||||||
@ -347,7 +350,7 @@ namespace skyline::nce {
|
|||||||
|
|
||||||
/* Restore Scratch Registers and Return */
|
/* Restore Scratch Registers and Return */
|
||||||
*patch++ = x0x1 ? 0xA8C107E0 : 0xA8C10FE2; // LDP X(0/2), X(1/3), [SP], #16
|
*patch++ = x0x1 ? 0xA8C107E0 : 0xA8C10FE2; // LDP X(0/2), X(1/3), [SP], #16
|
||||||
*patch = instructions::B((end - patch) + offset + 1).raw;
|
*patch = instructions::B(static_cast<i32>(endOffset() + offset + 1)).raw;
|
||||||
patch++;
|
patch++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,13 +104,13 @@ namespace skyline::nce {
|
|||||||
/**
|
/**
|
||||||
* @param negate The direction of the supplied offset
|
* @param negate The direction of the supplied offset
|
||||||
*/
|
*/
|
||||||
constexpr B(i64 offset, bool negate = false) : offset(negate ? -offset : offset), sig(0x5) {}
|
constexpr B(i32 offset, bool negate = false) : offset(negate ? -offset : offset), sig(0x5) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The offset encoded within the instruction in bytes
|
* @return The offset encoded within the instruction in bytes
|
||||||
*/
|
*/
|
||||||
constexpr i32 Offset() {
|
constexpr i32 Offset() {
|
||||||
return offset * sizeof(u32);
|
return offset * static_cast<i32>(sizeof(u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool Verify() {
|
constexpr bool Verify() {
|
||||||
@ -138,7 +138,7 @@ namespace skyline::nce {
|
|||||||
* @return The offset encoded within the instruction in bytes
|
* @return The offset encoded within the instruction in bytes
|
||||||
*/
|
*/
|
||||||
constexpr i32 Offset() {
|
constexpr i32 Offset() {
|
||||||
return offset * sizeof(u32);
|
return offset * static_cast<i32>(sizeof(u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool Verify() {
|
constexpr bool Verify() {
|
||||||
|
@ -8,7 +8,7 @@ namespace skyline::service::am {
|
|||||||
IStorageAccessor::IStorageAccessor(const DeviceState &state, ServiceManager &manager, std::shared_ptr<IStorage> parent) : parent(std::move(parent)), BaseService(state, manager) {}
|
IStorageAccessor::IStorageAccessor(const DeviceState &state, ServiceManager &manager, std::shared_ptr<IStorage> parent) : parent(std::move(parent)), BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IStorageAccessor::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IStorageAccessor::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
response.Push<i64>(parent->content.size());
|
response.Push<i64>(static_cast<i64>(parent->content.size()));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ namespace skyline::service::am {
|
|||||||
if (offset < 0 || offset > parent->content.size())
|
if (offset < 0 || offset > parent->content.size())
|
||||||
return result::OutOfBounds;
|
return result::OutOfBounds;
|
||||||
|
|
||||||
auto size{std::min(static_cast<i64>(request.inputBuf.at(0).size()), static_cast<i64>(parent->content.size()) - offset)};
|
size_t size{std::min(request.inputBuf.at(0).size(), parent->content.size() - static_cast<size_t>(offset))};
|
||||||
|
|
||||||
if (size)
|
if (size)
|
||||||
span(parent->content).copy_from(request.inputBuf.at(0), size);
|
span(parent->content).copy_from(request.inputBuf.at(0), size);
|
||||||
@ -32,7 +32,7 @@ namespace skyline::service::am {
|
|||||||
if (offset < 0 || offset > parent->content.size())
|
if (offset < 0 || offset > parent->content.size())
|
||||||
return result::OutOfBounds;
|
return result::OutOfBounds;
|
||||||
|
|
||||||
auto size{std::min(static_cast<i64>(request.outputBuf.at(0).size()), static_cast<i64>(parent->content.size()) - offset)};
|
size_t size{std::min(request.outputBuf.at(0).size(), parent->content.size() - static_cast<size_t>(offset))};
|
||||||
|
|
||||||
if (size)
|
if (size)
|
||||||
request.outputBuf.at(0).copy_from(span(parent->content.data() + offset, size));
|
request.outputBuf.at(0).copy_from(span(parent->content.data() + offset, size));
|
||||||
|
@ -26,7 +26,7 @@ namespace skyline::service::audio {
|
|||||||
|
|
||||||
u32 totalMixCount{params.subMixCount + 1};
|
u32 totalMixCount{params.subMixCount + 1};
|
||||||
|
|
||||||
i64 size{util::AlignUp(params.mixBufferCount * 4, constant::BufferAlignment) +
|
u64 size{util::AlignUp(params.mixBufferCount * 4, constant::BufferAlignment) +
|
||||||
params.subMixCount * 0x400 +
|
params.subMixCount * 0x400 +
|
||||||
totalMixCount * 0x940 +
|
totalMixCount * 0x940 +
|
||||||
params.voiceCount * 0x3F0 +
|
params.voiceCount * 0x3F0 +
|
||||||
@ -35,21 +35,21 @@ namespace skyline::service::audio {
|
|||||||
util::AlignUp(((params.sinkCount + params.subMixCount) * 0x3C0 + params.sampleCount * 4) * (params.mixBufferCount + 6), constant::BufferAlignment) + (params.sinkCount + params.subMixCount) * 0x2C0 + (params.effectCount + params.voiceCount * 4) * 0x30 + 0x50};
|
util::AlignUp(((params.sinkCount + params.subMixCount) * 0x3C0 + params.sampleCount * 4) * (params.mixBufferCount + 6), constant::BufferAlignment) + (params.sinkCount + params.subMixCount) * 0x2C0 + (params.effectCount + params.voiceCount * 4) * 0x30 + 0x50};
|
||||||
|
|
||||||
if (revisionInfo.SplitterSupported()) {
|
if (revisionInfo.SplitterSupported()) {
|
||||||
i32 nodeStateWorkSize{util::AlignUp<i32>(totalMixCount, constant::BufferAlignment)};
|
i32 nodeStateWorkSize{static_cast<i32>(util::AlignUp(totalMixCount, constant::BufferAlignment))};
|
||||||
if (nodeStateWorkSize < 0)
|
if (nodeStateWorkSize < 0)
|
||||||
nodeStateWorkSize |= 7;
|
nodeStateWorkSize |= 7;
|
||||||
|
|
||||||
nodeStateWorkSize = 4 * (totalMixCount * totalMixCount) + 12 * totalMixCount + 2 * (nodeStateWorkSize / 8);
|
nodeStateWorkSize = static_cast<i32>(4 * (totalMixCount * totalMixCount) + 12 * totalMixCount + static_cast<u32>(2 * (nodeStateWorkSize / 8)));
|
||||||
|
|
||||||
i32 edgeMatrixWorkSize{util::AlignUp<i32>(totalMixCount * totalMixCount, constant::BufferAlignment)};
|
i32 edgeMatrixWorkSize{static_cast<i32>(util::AlignUp(totalMixCount * totalMixCount, constant::BufferAlignment))};
|
||||||
if (edgeMatrixWorkSize < 0)
|
if (edgeMatrixWorkSize < 0)
|
||||||
edgeMatrixWorkSize |= 7;
|
edgeMatrixWorkSize |= 7;
|
||||||
|
|
||||||
edgeMatrixWorkSize /= 8;
|
edgeMatrixWorkSize /= 8;
|
||||||
size += util::AlignUp(edgeMatrixWorkSize + nodeStateWorkSize, 16);
|
size += util::AlignUp(static_cast<u32>(edgeMatrixWorkSize + nodeStateWorkSize), 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 splitterWorkSize{};
|
u64 splitterWorkSize{};
|
||||||
if (revisionInfo.SplitterSupported()) {
|
if (revisionInfo.SplitterSupported()) {
|
||||||
splitterWorkSize += params.splitterDestinationDataCount * 0xE0 + params.splitterCount * 0x20;
|
splitterWorkSize += params.splitterDestinationDataCount * 0xE0 + params.splitterCount * 0x20;
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ namespace skyline::service::audio {
|
|||||||
splitterWorkSize += util::AlignUp(4 * params.splitterDestinationDataCount, 16);
|
splitterWorkSize += util::AlignUp(4 * params.splitterDestinationDataCount, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
size = params.sinkCount * 0x170 + (params.sinkCount + params.subMixCount) * 0x280 + params.effectCount * 0x4C0 + ((size + splitterWorkSize + 0x30 * params.effectCount + (4 * params.voiceCount) + 0x8F) & ~0x3FL) + ((params.voiceCount << 8) | 0x40);
|
size = params.sinkCount * 0x170 + (params.sinkCount + params.subMixCount) * 0x280 + params.effectCount * 0x4C0 + ((size + splitterWorkSize + 0x30 * params.effectCount + (4 * params.voiceCount) + 0x8F) & ~0x3FUL) + ((params.voiceCount << 8) | 0x40);
|
||||||
|
|
||||||
if (params.performanceManagerCount > 0) {
|
if (params.performanceManagerCount > 0) {
|
||||||
i64 performanceMetricsBufferSize{};
|
i64 performanceMetricsBufferSize{};
|
||||||
@ -67,7 +67,7 @@ namespace skyline::service::audio {
|
|||||||
performanceMetricsBufferSize = ((static_cast<i64>((params.voiceCount + params.effectCount + totalMixCount + params.sinkCount)) << 32) >> 0x1C) + 0x658;
|
performanceMetricsBufferSize = ((static_cast<i64>((params.voiceCount + params.effectCount + totalMixCount + params.sinkCount)) << 32) >> 0x1C) + 0x658;
|
||||||
}
|
}
|
||||||
|
|
||||||
size += (performanceMetricsBufferSize * (params.performanceManagerCount + 1) + 0xFF) & ~0x3FL;
|
size += static_cast<u64>((performanceMetricsBufferSize * (params.performanceManagerCount + 1) + 0xFF) & ~0x3FL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (revisionInfo.VaradicCommandBufferSizeSupported()) {
|
if (revisionInfo.VaradicCommandBufferSizeSupported()) {
|
||||||
@ -79,7 +79,7 @@ namespace skyline::service::audio {
|
|||||||
size = util::AlignUp(size, 0x1000);
|
size = util::AlignUp(size, 0x1000);
|
||||||
|
|
||||||
state.logger->Debug("Work buffer size: 0x{:X}", size);
|
state.logger->Debug("Work buffer size: 0x{:X}", size);
|
||||||
response.Push<i64>(size);
|
response.Push<u64>(size);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
#include "IHardwareOpusDecoder.h"
|
#include "IHardwareOpusDecoder.h"
|
||||||
|
|
||||||
namespace skyline::service::codec {
|
namespace skyline::service::codec {
|
||||||
size_t CalculateOutBufferSize(i32 sampleRate, i32 channelCount, i32 frameSize) {
|
u32 CalculateOutBufferSize(i32 sampleRate, i32 channelCount, i32 frameSize) {
|
||||||
return util::AlignUp(frameSize * channelCount / (OpusFullbandSampleRate / sampleRate), 0x40);
|
return util::AlignUp(static_cast<u32>(frameSize * channelCount / (OpusFullbandSampleRate / sampleRate)), 0x40);
|
||||||
}
|
}
|
||||||
|
|
||||||
IHardwareOpusDecoder::IHardwareOpusDecoder(const DeviceState &state, ServiceManager &manager, i32 sampleRate, i32 channelCount, u32 workBufferSize, KHandle workBufferHandle)
|
IHardwareOpusDecoder::IHardwareOpusDecoder(const DeviceState &state, ServiceManager &manager, i32 sampleRate, i32 channelCount, u32 workBufferSize, KHandle workBufferHandle)
|
||||||
@ -54,8 +54,8 @@ namespace skyline::service::codec {
|
|||||||
if (dataIn.size() <= sizeof(OpusDataHeader))
|
if (dataIn.size() <= sizeof(OpusDataHeader))
|
||||||
throw exception("Incorrect Opus data size: 0x{:X} (Should be > 0x{:X})", dataIn.size(), sizeof(OpusDataHeader));
|
throw exception("Incorrect Opus data size: 0x{:X} (Should be > 0x{:X})", dataIn.size(), sizeof(OpusDataHeader));
|
||||||
|
|
||||||
u32 opusPacketSize{dataIn.as<OpusDataHeader>().GetPacketSize()};
|
i32 opusPacketSize{dataIn.as<OpusDataHeader>().GetPacketSize()};
|
||||||
i32 requiredInSize{static_cast<i32>(opusPacketSize + sizeof(OpusDataHeader))};
|
i32 requiredInSize{opusPacketSize + static_cast<i32>(sizeof(OpusDataHeader))};
|
||||||
if (opusPacketSize > MaxInputBufferSize || dataIn.size() < requiredInSize)
|
if (opusPacketSize > MaxInputBufferSize || dataIn.size() < requiredInSize)
|
||||||
throw exception("Opus packet size mismatch: 0x{:X} (Requested: 0x{:X})", dataIn.size() - sizeof(OpusDataHeader), opusPacketSize);
|
throw exception("Opus packet size mismatch: 0x{:X} (Requested: 0x{:X})", dataIn.size() - sizeof(OpusDataHeader), opusPacketSize);
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ namespace skyline::service::codec {
|
|||||||
auto sampleDataIn = dataIn.subspan(sizeof(OpusDataHeader));
|
auto sampleDataIn = dataIn.subspan(sizeof(OpusDataHeader));
|
||||||
|
|
||||||
auto perfTimer{timesrv::TimeSpanType::FromNanoseconds(util::GetTimeNs())};
|
auto perfTimer{timesrv::TimeSpanType::FromNanoseconds(util::GetTimeNs())};
|
||||||
i32 decodedCount{opus_decode(decoderState, sampleDataIn.data(), opusPacketSize, dataOut.data(), decoderOutputBufferSize, false)};
|
i32 decodedCount{opus_decode(decoderState, sampleDataIn.data(), opusPacketSize, dataOut.data(), static_cast<int>(decoderOutputBufferSize), false)};
|
||||||
perfTimer = timesrv::TimeSpanType::FromNanoseconds(util::GetTimeNs()) - perfTimer;
|
perfTimer = timesrv::TimeSpanType::FromNanoseconds(util::GetTimeNs()) - perfTimer;
|
||||||
|
|
||||||
if (decodedCount < 0)
|
if (decodedCount < 0)
|
||||||
@ -72,7 +72,7 @@ namespace skyline::service::codec {
|
|||||||
response.Push(requiredInSize); // Decoded data size is equal to opus packet size + header
|
response.Push(requiredInSize); // Decoded data size is equal to opus packet size + header
|
||||||
response.Push(decodedCount);
|
response.Push(decodedCount);
|
||||||
if (writeDecodeTime)
|
if (writeDecodeTime)
|
||||||
response.Push<u64>(perfTimer.Microseconds());
|
response.Push<i64>(perfTimer.Microseconds());
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,11 @@ namespace skyline::service::codec {
|
|||||||
/**
|
/**
|
||||||
* @return The required output buffer size for decoding an Opus stream with the given parameters
|
* @return The required output buffer size for decoding an Opus stream with the given parameters
|
||||||
*/
|
*/
|
||||||
size_t CalculateOutBufferSize(i32 sampleRate, i32 channelCount, i32 frameSize);
|
u32 CalculateOutBufferSize(i32 sampleRate, i32 channelCount, i32 frameSize);
|
||||||
|
|
||||||
static constexpr u32 OpusFullbandSampleRate{48000};
|
static constexpr i32 OpusFullbandSampleRate{48000};
|
||||||
static constexpr u32 MaxFrameSizeNormal = OpusFullbandSampleRate * 0.040; //!< 40ms frame size limit for normal decoders
|
static constexpr i32 MaxFrameSizeNormal{static_cast<u32>(OpusFullbandSampleRate * 0.040f)}; //!< 40ms frame size limit for normal decoders
|
||||||
static constexpr u32 MaxFrameSizeEx = OpusFullbandSampleRate * 0.120; //!< 120ms frame size limit for ex decoders added in 12.0.0
|
static constexpr i32 MaxFrameSizeEx{static_cast<u32>(OpusFullbandSampleRate * 0.120f)}; //!< 120ms frame size limit for ex decoders added in 12.0.0
|
||||||
static constexpr u32 MaxInputBufferSize{0x600}; //!< Maximum allocated size of the input buffer
|
static constexpr u32 MaxInputBufferSize{0x600}; //!< Maximum allocated size of the input buffer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,7 +30,7 @@ namespace skyline::service::codec {
|
|||||||
OpusDecoder *decoderState{};
|
OpusDecoder *decoderState{};
|
||||||
i32 sampleRate;
|
i32 sampleRate;
|
||||||
i32 channelCount;
|
i32 channelCount;
|
||||||
i32 decoderOutputBufferSize;
|
u32 decoderOutputBufferSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Holds information about the Opus packet to be decoded
|
* @brief Holds information about the Opus packet to be decoded
|
||||||
@ -41,8 +41,8 @@ namespace skyline::service::codec {
|
|||||||
u32 sizeBe; //!< Size of the packet following this header
|
u32 sizeBe; //!< Size of the packet following this header
|
||||||
u32 finalRangeBe; //!< Final range of the codec encoder's entropy coder (can be zero)
|
u32 finalRangeBe; //!< Final range of the codec encoder's entropy coder (can be zero)
|
||||||
|
|
||||||
u32 GetPacketSize() {
|
i32 GetPacketSize() {
|
||||||
return util::SwapEndianness(sizeBe);
|
return static_cast<i32>(util::SwapEndianness(sizeBe));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static_assert(sizeof(OpusDataHeader) == 0x8);
|
static_assert(sizeof(OpusDataHeader) == 0x8);
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
#include "IHardwareOpusDecoder.h"
|
#include "IHardwareOpusDecoder.h"
|
||||||
|
|
||||||
namespace skyline::service::codec {
|
namespace skyline::service::codec {
|
||||||
static size_t CalculateBufferSize(i32 sampleRate, i32 channelCount) {
|
static u32 CalculateBufferSize(i32 sampleRate, i32 channelCount) {
|
||||||
i32 requiredSize{opus_decoder_get_size(channelCount)};
|
u32 requiredSize{static_cast<u32>(opus_decoder_get_size(channelCount))};
|
||||||
requiredSize += MaxInputBufferSize + CalculateOutBufferSize(sampleRate, channelCount, MaxFrameSizeNormal);
|
requiredSize += MaxInputBufferSize + CalculateOutBufferSize(sampleRate, channelCount, MaxFrameSizeNormal);
|
||||||
return requiredSize;
|
return requiredSize;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ namespace skyline::service::fssrv {
|
|||||||
return result::InvalidSize;
|
return result::InvalidSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Push<u32>(static_cast<u32>(backing->ReadUnchecked(request.outputBuf.at(0), offset)));
|
response.Push<u64>(backing->ReadUnchecked(request.outputBuf.at(0), static_cast<size_t>(offset)));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ namespace skyline::service::fssrv {
|
|||||||
return result::InvalidSize;
|
return result::InvalidSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backing->Write(request.inputBuf.at(0), offset) != size) {
|
if (backing->Write(request.inputBuf.at(0), static_cast<size_t>(offset)) != size) {
|
||||||
state.logger->Warn("Failed to write all data to the backing");
|
state.logger->Warn("Failed to write all data to the backing");
|
||||||
return result::UnexpectedFailure;
|
return result::UnexpectedFailure;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace skyline::service::fssrv {
|
|||||||
return result::InvalidSize;
|
return result::InvalidSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
backing->Read(request.outputBuf.at(0), offset);
|
backing->Read(request.outputBuf.at(0), static_cast<size_t>(offset));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ namespace skyline::service::glue {
|
|||||||
|
|
||||||
outList.copy_from(span(timesrvCore.locationNameList).subspan(offset, outList.size()));
|
outList.copy_from(span(timesrvCore.locationNameList).subspan(offset, outList.size()));
|
||||||
|
|
||||||
response.Push<u32>(outList.size());
|
response.Push(static_cast<u32>(outList.size()));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ namespace skyline::service::hid {
|
|||||||
|
|
||||||
Result IHidServer::GetPlayerLedPattern(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IHidServer::GetPlayerLedPattern(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto id{request.Pop<NpadId>()};
|
auto id{request.Pop<NpadId>()};
|
||||||
response.Push<u64>([id] {
|
response.Push<u64>([id]() -> u64 {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case NpadId::Player1:
|
case NpadId::Player1:
|
||||||
return 0b0001;
|
return 0b0001;
|
||||||
|
@ -34,7 +34,7 @@ namespace skyline::service::hosbinder {
|
|||||||
return AndroidStatus::BadValue;
|
return AndroidStatus::BadValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &bufferSlot{queue[slot]};
|
auto &bufferSlot{queue[static_cast<size_t>(slot)]};
|
||||||
bufferSlot.wasBufferRequested = true;
|
bufferSlot.wasBufferRequested = true;
|
||||||
buffer = bufferSlot.graphicBuffer.get();
|
buffer = bufferSlot.graphicBuffer.get();
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ namespace skyline::service::hosbinder {
|
|||||||
state.logger->Warn("Setting the active slot count ({}) higher than the amount of slots with preallocated buffers ({})", count, preallocatedBufferCount);
|
state.logger->Warn("Setting the active slot count ({}) higher than the amount of slots with preallocated buffers ({})", count, preallocatedBufferCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
activeSlotCount = count;
|
activeSlotCount = static_cast<u8>(count);
|
||||||
bufferEvent->Signal();
|
bufferEvent->Signal();
|
||||||
|
|
||||||
return AndroidStatus::Ok;
|
return AndroidStatus::Ok;
|
||||||
@ -157,7 +157,7 @@ namespace skyline::service::hosbinder {
|
|||||||
return AndroidStatus::BadValue;
|
return AndroidStatus::BadValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &bufferSlot{queue[slot]};
|
auto &bufferSlot{queue[static_cast<size_t>(slot)]};
|
||||||
if (bufferSlot.state != BufferState::Dequeued) [[unlikely]] {
|
if (bufferSlot.state != BufferState::Dequeued) [[unlikely]] {
|
||||||
state.logger->Warn("#{} was '{}' instead of being dequeued", slot, ToString(bufferSlot.state));
|
state.logger->Warn("#{} was '{}' instead of being dequeued", slot, ToString(bufferSlot.state));
|
||||||
return AndroidStatus::BadValue;
|
return AndroidStatus::BadValue;
|
||||||
@ -245,10 +245,10 @@ namespace skyline::service::hosbinder {
|
|||||||
FreeGraphicBufferNvMap(*bufferSlot->graphicBuffer);
|
FreeGraphicBufferNvMap(*bufferSlot->graphicBuffer);
|
||||||
bufferSlot->graphicBuffer = std::make_unique<GraphicBuffer>(graphicBuffer);
|
bufferSlot->graphicBuffer = std::make_unique<GraphicBuffer>(graphicBuffer);
|
||||||
|
|
||||||
slot = std::distance(queue.begin(), bufferSlot);
|
slot = static_cast<u8>(std::distance(queue.begin(), bufferSlot));
|
||||||
|
|
||||||
preallocatedBufferCount = std::count_if(queue.begin(), queue.end(), [](const BufferSlot &slot) { return slot.graphicBuffer && slot.isPreallocated; });
|
preallocatedBufferCount = static_cast<u8>(std::count_if(queue.begin(), queue.end(), [](const auto &slot) { return slot.graphicBuffer && slot.isPreallocated; }));
|
||||||
activeSlotCount = std::count_if(queue.begin(), queue.end(), [](const BufferSlot &slot) { return slot.graphicBuffer != nullptr; });
|
activeSlotCount = static_cast<u8>(std::count_if(queue.begin(), queue.end(), [](const auto &slot) { return slot.graphicBuffer != nullptr; }));
|
||||||
|
|
||||||
state.logger->Debug("#{} - Dimensions: {}x{} [Stride: {}], Format: {}, Layout: {}, {}: {}, Usage: 0x{:X}, NvMap {}: {}, Buffer Start/End: 0x{:X} -> 0x{:X}", slot, surface.width, surface.height, handle.stride, ToString(handle.format), ToString(surface.layout), surface.layout == NvSurfaceLayout::Blocklinear ? "Block Height" : "Pitch", surface.layout == NvSurfaceLayout::Blocklinear ? 1U << surface.blockHeightLog2 : surface.pitch, graphicBuffer.usage, surface.nvmapHandle ? "Handle" : "ID", surface.nvmapHandle ? surface.nvmapHandle : handle.nvmapId, surface.offset, surface.offset + surface.size);
|
state.logger->Debug("#{} - Dimensions: {}x{} [Stride: {}], Format: {}, Layout: {}, {}: {}, Usage: 0x{:X}, NvMap {}: {}, Buffer Start/End: 0x{:X} -> 0x{:X}", slot, surface.width, surface.height, handle.stride, ToString(handle.format), ToString(surface.layout), surface.layout == NvSurfaceLayout::Blocklinear ? "Block Height" : "Pitch", surface.layout == NvSurfaceLayout::Blocklinear ? 1U << surface.blockHeightLog2 : surface.pitch, graphicBuffer.usage, surface.nvmapHandle ? "Handle" : "ID", surface.nvmapHandle ? surface.nvmapHandle : handle.nvmapId, surface.offset, surface.offset + surface.size);
|
||||||
return AndroidStatus::Ok;
|
return AndroidStatus::Ok;
|
||||||
@ -273,7 +273,7 @@ namespace skyline::service::hosbinder {
|
|||||||
return AndroidStatus::BadValue;
|
return AndroidStatus::BadValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &buffer{queue[slot]};
|
auto &buffer{queue[static_cast<size_t>(slot)]};
|
||||||
if (buffer.state != BufferState::Dequeued) [[unlikely]] {
|
if (buffer.state != BufferState::Dequeued) [[unlikely]] {
|
||||||
state.logger->Warn("#{} was '{}' instead of being dequeued", slot, ToString(buffer.state));
|
state.logger->Warn("#{} was '{}' instead of being dequeued", slot, ToString(buffer.state));
|
||||||
return AndroidStatus::BadValue;
|
return AndroidStatus::BadValue;
|
||||||
@ -411,7 +411,7 @@ namespace skyline::service::hosbinder {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &buffer{queue[slot]};
|
auto &buffer{queue[static_cast<size_t>(slot)]};
|
||||||
if (buffer.state != BufferState::Dequeued) [[unlikely]] {
|
if (buffer.state != BufferState::Dequeued) [[unlikely]] {
|
||||||
state.logger->Warn("#{} is not owned by the producer as it is '{}' instead of being dequeued", slot, ToString(buffer.state));
|
state.logger->Warn("#{} is not owned by the producer as it is '{}' instead of being dequeued", slot, ToString(buffer.state));
|
||||||
return;
|
return;
|
||||||
@ -544,7 +544,7 @@ namespace skyline::service::hosbinder {
|
|||||||
return AndroidStatus::BadValue;
|
return AndroidStatus::BadValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &buffer{queue[slot]};
|
auto &buffer{queue[static_cast<size_t>(slot)]};
|
||||||
buffer.state = BufferState::Free;
|
buffer.state = BufferState::Free;
|
||||||
buffer.frameNumber = 0;
|
buffer.frameNumber = 0;
|
||||||
buffer.wasBufferRequested = false;
|
buffer.wasBufferRequested = false;
|
||||||
@ -578,8 +578,8 @@ namespace skyline::service::hosbinder {
|
|||||||
state.logger->Debug("#{} - No GraphicBuffer", slot);
|
state.logger->Debug("#{} - No GraphicBuffer", slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
preallocatedBufferCount = std::count_if(queue.begin(), queue.end(), [](const BufferSlot &slot) { return slot.graphicBuffer && slot.isPreallocated; });
|
preallocatedBufferCount = static_cast<u8>(std::count_if(queue.begin(), queue.end(), [](const BufferSlot &slot) { return slot.graphicBuffer && slot.isPreallocated; }));
|
||||||
activeSlotCount = std::count_if(queue.begin(), queue.end(), [](const BufferSlot &slot) { return slot.graphicBuffer != nullptr; });
|
activeSlotCount = static_cast<u8>(std::count_if(queue.begin(), queue.end(), [](const BufferSlot &slot) { return slot.graphicBuffer != nullptr; }));
|
||||||
|
|
||||||
bufferEvent->Signal();
|
bufferEvent->Signal();
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ namespace skyline::service::hosbinder {
|
|||||||
header.dataOffset = sizeof(ParcelHeader);
|
header.dataOffset = sizeof(ParcelHeader);
|
||||||
|
|
||||||
header.objectsSize = static_cast<u32>(objects.size());
|
header.objectsSize = static_cast<u32>(objects.size());
|
||||||
header.objectsOffset = sizeof(ParcelHeader) + data.size();
|
header.objectsOffset = static_cast<u32>(sizeof(ParcelHeader) + data.size());
|
||||||
|
|
||||||
auto totalSize{sizeof(ParcelHeader) + header.dataSize + header.objectsSize};
|
auto totalSize{sizeof(ParcelHeader) + header.dataSize + header.objectsSize};
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result INvDrvServices::Close(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result INvDrvServices::Close(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto fd{request.Pop<u32>()};
|
auto fd{request.Pop<FileDescriptor>()};
|
||||||
state.logger->Debug("Closing NVDRV device ({})", fd);
|
state.logger->Debug("Closing NVDRV device ({})", fd);
|
||||||
|
|
||||||
driver.CloseDevice(fd);
|
driver.CloseDevice(fd);
|
||||||
@ -85,7 +85,7 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result INvDrvServices::QueryEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result INvDrvServices::QueryEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto fd{request.Pop<u32>()};
|
auto fd{request.Pop<FileDescriptor>()};
|
||||||
auto eventId{request.Pop<u32>()};
|
auto eventId{request.Pop<u32>()};
|
||||||
|
|
||||||
auto event{driver.QueryEvent(fd, eventId)};
|
auto event{driver.QueryEvent(fd, eventId)};
|
||||||
|
@ -106,11 +106,11 @@ namespace skyline::service::nvdrv::deserialisation {
|
|||||||
constexpr static u32 Raw() {
|
constexpr static u32 Raw() {
|
||||||
u32 raw{Function};
|
u32 raw{Function};
|
||||||
|
|
||||||
i8 offset{8};
|
int offset{8};
|
||||||
raw |= Magic << offset; offset += 8;
|
raw |= static_cast<u32>(Magic << offset); offset += 8;
|
||||||
raw |= Size << offset; offset += 14;
|
raw |= static_cast<u32>(Size << offset); offset += 14;
|
||||||
raw |= In << offset; offset++;
|
raw |= (In ? 1U : 0U) << offset; offset++;
|
||||||
raw |= Out << offset; offset++;
|
raw |= (Out ? 1U : 0U) << offset; offset++;
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -130,10 +130,10 @@ namespace skyline::service::nvdrv::deserialisation {
|
|||||||
u32 raw{Function};
|
u32 raw{Function};
|
||||||
|
|
||||||
i8 offset{8};
|
i8 offset{8};
|
||||||
raw |= Magic << offset; offset += 8;
|
raw |= static_cast<u32>(Magic << offset); offset += 8;
|
||||||
offset += 14; // Use a 0 size for raw
|
offset += 14; // Use a 0 size for raw
|
||||||
raw |= In << offset; offset++;
|
raw |= (In ? 1U : 0U) << offset; offset++;
|
||||||
raw |= Out << offset; offset++;
|
raw |= (Out ? 1U : 0U) << offset; offset++;
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -66,7 +66,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
|||||||
auto &allocator{pageSize == VM::PageSize ? *vm.smallPageAllocator : *vm.bigPageAllocator};
|
auto &allocator{pageSize == VM::PageSize ? *vm.smallPageAllocator : *vm.bigPageAllocator};
|
||||||
|
|
||||||
if (flags.fixed)
|
if (flags.fixed)
|
||||||
allocator.AllocateFixed(offset >> pageSizeBits, pages);
|
allocator.AllocateFixed(static_cast<u32>(offset >> pageSizeBits), pages);
|
||||||
else
|
else
|
||||||
offset = static_cast<u64>(allocator.Allocate(pages)) << pageSizeBits;
|
offset = static_cast<u64>(allocator.Allocate(pages)) << pageSizeBits;
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
|||||||
auto &allocator{mapping->bigPage ? *vm.bigPageAllocator : *vm.smallPageAllocator};
|
auto &allocator{mapping->bigPage ? *vm.bigPageAllocator : *vm.smallPageAllocator};
|
||||||
u32 pageSizeBits{mapping->bigPage ? vm.bigPageSizeBits : VM::PageSizeBits};
|
u32 pageSizeBits{mapping->bigPage ? vm.bigPageSizeBits : VM::PageSizeBits};
|
||||||
|
|
||||||
allocator.Free(mapping->offset >> pageSizeBits, mapping->size >> pageSizeBits);
|
allocator.Free(static_cast<u32>(mapping->offset >> pageSizeBits), static_cast<u32>(mapping->size >> pageSizeBits));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sparse mappings shouldn't be fully unmapped, just returned to their sparse state
|
// Sparse mappings shouldn't be fully unmapped, just returned to their sparse state
|
||||||
@ -128,7 +128,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
|||||||
auto &allocator{pageSize == VM::PageSize ? *vm.smallPageAllocator : *vm.bigPageAllocator};
|
auto &allocator{pageSize == VM::PageSize ? *vm.smallPageAllocator : *vm.bigPageAllocator};
|
||||||
u32 pageSizeBits{pageSize == VM::PageSize ? VM::PageSizeBits : vm.bigPageSizeBits};
|
u32 pageSizeBits{pageSize == VM::PageSize ? VM::PageSizeBits : vm.bigPageSizeBits};
|
||||||
|
|
||||||
allocator.Free(offset >> pageSizeBits, allocation.size >> pageSizeBits);
|
allocator.Free(static_cast<u32>(offset >> pageSizeBits), static_cast<u32>(allocation.size >> pageSizeBits));
|
||||||
allocationMap.erase(offset);
|
allocationMap.erase(offset);
|
||||||
} catch (const std::out_of_range &e) {
|
} catch (const std::out_of_range &e) {
|
||||||
return PosixResult::InvalidArgument;
|
return PosixResult::InvalidArgument;
|
||||||
@ -152,7 +152,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
|||||||
auto &allocator{mapping->bigPage ? *vm.bigPageAllocator : *vm.smallPageAllocator};
|
auto &allocator{mapping->bigPage ? *vm.bigPageAllocator : *vm.smallPageAllocator};
|
||||||
u32 pageSizeBits{mapping->bigPage ? vm.bigPageSizeBits : VM::PageSizeBits};
|
u32 pageSizeBits{mapping->bigPage ? vm.bigPageSizeBits : VM::PageSizeBits};
|
||||||
|
|
||||||
allocator.Free(mapping->offset >> pageSizeBits, mapping->size >> pageSizeBits);
|
allocator.Free(static_cast<u32>(mapping->offset >> pageSizeBits), static_cast<u32>(mapping->size >> pageSizeBits));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sparse mappings shouldn't be fully unmapped, just returned to their sparse state
|
// Sparse mappings shouldn't be fully unmapped, just returned to their sparse state
|
||||||
@ -235,7 +235,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
|||||||
u32 pageSize{bigPage ? vm.bigPageSize : VM::PageSize};
|
u32 pageSize{bigPage ? vm.bigPageSize : VM::PageSize};
|
||||||
u32 pageSizeBits{bigPage ? vm.bigPageSizeBits : VM::PageSizeBits};
|
u32 pageSizeBits{bigPage ? vm.bigPageSizeBits : VM::PageSizeBits};
|
||||||
|
|
||||||
offset = static_cast<u64>(allocator.Allocate(util::AlignUp(size, pageSize) >> pageSizeBits)) << pageSizeBits;
|
offset = static_cast<u64>(allocator.Allocate(static_cast<u32>(util::AlignUp(size, pageSize) >> pageSizeBits))) << pageSizeBits;
|
||||||
asCtx->gmmu.Map(offset, cpuPtr, size);
|
asCtx->gmmu.Map(offset, cpuPtr, size);
|
||||||
|
|
||||||
auto mapping{std::make_shared<Mapping>(cpuPtr, offset, size, false, bigPage, false)};
|
auto mapping{std::make_shared<Mapping>(cpuPtr, offset, size, false, bigPage, false)};
|
||||||
@ -297,7 +297,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vm.bigPageSize = bigPageSize;
|
vm.bigPageSize = bigPageSize;
|
||||||
vm.bigPageSizeBits = std::countr_zero(bigPageSize);
|
vm.bigPageSizeBits = static_cast<u32>(std::countr_zero(bigPageSize));
|
||||||
|
|
||||||
vm.vaRangeStart = bigPageSize << VM::VaStartShift;
|
vm.vaRangeStart = bigPageSize << VM::VaStartShift;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
|||||||
value.val = 0;
|
value.val = 0;
|
||||||
|
|
||||||
if (allocate) {
|
if (allocate) {
|
||||||
value.syncpointIdForAllocation = fence.id;
|
value.syncpointIdForAllocation = static_cast<u16>(fence.id);
|
||||||
value.eventAllocated = true;
|
value.eventAllocated = true;
|
||||||
} else {
|
} else {
|
||||||
value.syncpointId = fence.id;
|
value.syncpointId = fence.id;
|
||||||
@ -215,11 +215,10 @@ namespace skyline::service::nvdrv::device::nvhost {
|
|||||||
// Avoid repeated locks/unlocks by just locking now
|
// Avoid repeated locks/unlocks by just locking now
|
||||||
std::lock_guard lock(syncpointEventMutex);
|
std::lock_guard lock(syncpointEventMutex);
|
||||||
|
|
||||||
for (int i{}; i < 64; i++) {
|
for (u32 i{}; i < std::numeric_limits<u64>::digits; i++)
|
||||||
if (bitmask & (1 << i))
|
if (bitmask & (1 << i))
|
||||||
if (auto freeErr{SyncpointFreeEventLocked(i)}; freeErr != PosixResult::Success)
|
if (auto freeErr{SyncpointFreeEventLocked(i)}; freeErr != PosixResult::Success)
|
||||||
err = freeErr;
|
err = freeErr;
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
|||||||
pushBufferMemory.resize(pushBufferWords);
|
pushBufferMemory.resize(pushBufferWords);
|
||||||
|
|
||||||
// Allocate pages in the GPU AS
|
// Allocate pages in the GPU AS
|
||||||
pushBufferAddr = static_cast<u64>(asAllocator->Allocate((pushBufferWords >> AsGpu::VM::PageSizeBits) + 1)) << AsGpu::VM::PageSizeBits;
|
pushBufferAddr = static_cast<u64>(asAllocator->Allocate((static_cast<u32>(pushBufferWords) >> AsGpu::VM::PageSizeBits) + 1)) << AsGpu::VM::PageSizeBits;
|
||||||
|
|
||||||
// Map onto the GPU
|
// Map onto the GPU
|
||||||
asCtx->gmmu.Map(pushBufferAddr, reinterpret_cast<u8 *>(pushBufferMemory.data()), pushBufferSize);
|
asCtx->gmmu.Map(pushBufferAddr, reinterpret_cast<u8 *>(pushBufferMemory.data()), pushBufferSize);
|
||||||
|
@ -17,7 +17,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
|||||||
class GpuChannel : public NvDevice {
|
class GpuChannel : public NvDevice {
|
||||||
private:
|
private:
|
||||||
u32 channelSyncpoint{}; //!< The syncpoint for submissions allocated to this channel in `AllocGpfifo`
|
u32 channelSyncpoint{}; //!< The syncpoint for submissions allocated to this channel in `AllocGpfifo`
|
||||||
u32 channelUserData{};
|
u64 channelUserData{};
|
||||||
std::mutex channelMutex;
|
std::mutex channelMutex;
|
||||||
std::shared_ptr<type::KEvent> smExceptionBreakpointIntReportEvent;
|
std::shared_ptr<type::KEvent> smExceptionBreakpointIntReportEvent;
|
||||||
std::shared_ptr<type::KEvent> smExceptionBreakpointPauseReportEvent;
|
std::shared_ptr<type::KEvent> smExceptionBreakpointPauseReportEvent;
|
||||||
|
@ -9,7 +9,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
NvMap::NvMap(const DeviceState &state, Driver &driver, Core &core, const SessionContext &ctx) : NvDevice(state, driver, core, ctx) {}
|
NvMap::NvMap(const DeviceState &state, Driver &driver, Core &core, const SessionContext &ctx) : NvDevice(state, driver, core, ctx) {}
|
||||||
|
|
||||||
PosixResult NvMap::Create(In<u32> size, Out<NvMapCore::Handle::Id> handle) {
|
PosixResult NvMap::Create(In<u32> size, Out<NvMapCore::Handle::Id> handle) {
|
||||||
auto handleDesc{core.nvMap.CreateHandle(util::AlignUp(size, PAGE_SIZE))};
|
auto handleDesc{core.nvMap.CreateHandle(util::AlignUp(static_cast<u32>(size), PAGE_SIZE))};
|
||||||
if (handleDesc) {
|
if (handleDesc) {
|
||||||
(*handleDesc)->origSize = size; // Orig size is the unaligned size
|
(*handleDesc)->origSize = size; // Orig size is the unaligned size
|
||||||
handle = (*handleDesc)->id;
|
handle = (*handleDesc)->id;
|
||||||
@ -92,13 +92,13 @@ namespace skyline::service::nvdrv::device {
|
|||||||
|
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case HandleParameterType::Size:
|
case HandleParameterType::Size:
|
||||||
result = handleDesc->origSize;
|
result = static_cast<u32>(handleDesc->origSize);
|
||||||
return PosixResult::Success;
|
return PosixResult::Success;
|
||||||
case HandleParameterType::Alignment:
|
case HandleParameterType::Alignment:
|
||||||
result = handleDesc->align;
|
result = static_cast<u32>(handleDesc->align);
|
||||||
return PosixResult::Success;
|
return PosixResult::Success;
|
||||||
case HandleParameterType::Base:
|
case HandleParameterType::Base:
|
||||||
result = -static_cast<i32>(PosixResult::InvalidArgument);
|
result = static_cast<u32>(-static_cast<i32>(PosixResult::InvalidArgument));
|
||||||
return PosixResult::Success;
|
return PosixResult::Success;
|
||||||
case HandleParameterType::Heap:
|
case HandleParameterType::Heap:
|
||||||
if (handleDesc->allocated)
|
if (handleDesc->allocated)
|
||||||
|
@ -74,7 +74,7 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NvResult Driver::Ioctl(u32 fd, IoctlDescriptor cmd, span<u8> buffer) {
|
NvResult Driver::Ioctl(FileDescriptor fd, IoctlDescriptor cmd, span<u8> buffer) {
|
||||||
state.logger->Debug("fd: {}, cmd: 0x{:X}, device: {}", fd, cmd.raw, devices.at(fd)->GetName());
|
state.logger->Debug("fd: {}, cmd: 0x{:X}, device: {}", fd, cmd.raw, devices.at(fd)->GetName());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -85,7 +85,7 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NvResult Driver::Ioctl2(u32 fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer) {
|
NvResult Driver::Ioctl2(FileDescriptor fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer) {
|
||||||
state.logger->Debug("fd: {}, cmd: 0x{:X}, device: {}", fd, cmd.raw, devices.at(fd)->GetName());
|
state.logger->Debug("fd: {}, cmd: 0x{:X}, device: {}", fd, cmd.raw, devices.at(fd)->GetName());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -96,7 +96,7 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NvResult Driver::Ioctl3(u32 fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer) {
|
NvResult Driver::Ioctl3(FileDescriptor fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer) {
|
||||||
state.logger->Debug("fd: {}, cmd: 0x{:X}, device: {}", fd, cmd.raw, devices.at(fd)->GetName());
|
state.logger->Debug("fd: {}, cmd: 0x{:X}, device: {}", fd, cmd.raw, devices.at(fd)->GetName());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -107,7 +107,7 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Driver::CloseDevice(u32 fd) {
|
void Driver::CloseDevice(FileDescriptor fd) {
|
||||||
try {
|
try {
|
||||||
std::unique_lock lock(deviceMutex);
|
std::unique_lock lock(deviceMutex);
|
||||||
devices.erase(fd);
|
devices.erase(fd);
|
||||||
@ -116,7 +116,7 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<kernel::type::KEvent> Driver::QueryEvent(u32 fd, u32 eventId) {
|
std::shared_ptr<kernel::type::KEvent> Driver::QueryEvent(FileDescriptor fd, u32 eventId) {
|
||||||
state.logger->Debug("fd: {}, eventId: 0x{:X}, device: {}", fd, eventId, devices.at(fd)->GetName());
|
state.logger->Debug("fd: {}, eventId: 0x{:X}, device: {}", fd, eventId, devices.at(fd)->GetName());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -41,26 +41,26 @@ namespace skyline::service::nvdrv {
|
|||||||
/**
|
/**
|
||||||
* @brief Calls an IOCTL on the device specified by `fd`
|
* @brief Calls an IOCTL on the device specified by `fd`
|
||||||
*/
|
*/
|
||||||
NvResult Ioctl(u32 fd, IoctlDescriptor cmd, span<u8> buffer);
|
NvResult Ioctl(FileDescriptor fd, IoctlDescriptor cmd, span<u8> buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calls an IOCTL on the device specified by `fd` using the given inline input buffer
|
* @brief Calls an IOCTL on the device specified by `fd` using the given inline input buffer
|
||||||
*/
|
*/
|
||||||
NvResult Ioctl2(u32 fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer);
|
NvResult Ioctl2(FileDescriptor fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calls an IOCTL on the device specified by `fd` using the given inline output buffer
|
* @brief Calls an IOCTL on the device specified by `fd` using the given inline output buffer
|
||||||
*/
|
*/
|
||||||
NvResult Ioctl3(u32 fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer);
|
NvResult Ioctl3(FileDescriptor fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Queries a KEvent for the given `eventId` for the device specified by `fd`
|
* @brief Queries a KEvent for the given `eventId` for the device specified by `fd`
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<kernel::type::KEvent> QueryEvent(u32 fd, u32 eventId);
|
std::shared_ptr<kernel::type::KEvent> QueryEvent(FileDescriptor fd, u32 eventId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Closes the device specified by `fd`
|
* @brief Closes the device specified by `fd`
|
||||||
*/
|
*/
|
||||||
void CloseDevice(u32 fd);
|
void CloseDevice(FileDescriptor fd);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ namespace skyline::service::pl {
|
|||||||
|
|
||||||
struct FontEntry {
|
struct FontEntry {
|
||||||
std::string path; //!< The path of the font asset
|
std::string path; //!< The path of the font asset
|
||||||
size_t length; //!< The length of the font TTF data
|
u32 length; //!< The length of the font TTF data
|
||||||
size_t offset; //!< The offset of the font in shared memory
|
u32 offset; //!< The offset of the font in shared memory
|
||||||
};
|
};
|
||||||
|
|
||||||
std::array<FontEntry, 6> fonts{
|
std::array<FontEntry, 6> fonts{
|
||||||
@ -42,7 +42,7 @@ namespace skyline::service::pl {
|
|||||||
for (auto &font : fonts) {
|
for (auto &font : fonts) {
|
||||||
*ptr++ = 0x18029a7f;
|
*ptr++ = 0x18029a7f;
|
||||||
*ptr++ = util::SwapEndianness(font.length ^ 0x49621806);
|
*ptr++ = util::SwapEndianness(font.length ^ 0x49621806);
|
||||||
font.offset = reinterpret_cast<u64>(ptr) - reinterpret_cast<u64>(sharedFontMemory->host.ptr);
|
font.offset = static_cast<u32>(reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(sharedFontMemory->host.ptr));
|
||||||
|
|
||||||
std::shared_ptr<vfs::Backing> fontFile;
|
std::shared_ptr<vfs::Backing> fontFile;
|
||||||
if (fontsDirectory->FileExists(font.path))
|
if (fontsDirectory->FileExists(font.path))
|
||||||
@ -50,7 +50,7 @@ namespace skyline::service::pl {
|
|||||||
else
|
else
|
||||||
fontFile = state.os->assetFileSystem->OpenFile("fonts/" + font.path);
|
fontFile = state.os->assetFileSystem->OpenFile("fonts/" + font.path);
|
||||||
|
|
||||||
font.length = fontFile->size;
|
font.length = static_cast<u32>(fontFile->size);
|
||||||
fontFile->Read(span<u8>(reinterpret_cast<u8 *>(ptr), font.length));
|
fontFile->Read(span<u8>(reinterpret_cast<u8 *>(ptr), font.length));
|
||||||
ptr = reinterpret_cast<u32 *>(reinterpret_cast<u8 *>(ptr) + font.length);
|
ptr = reinterpret_cast<u32 *>(reinterpret_cast<u8 *>(ptr) + font.length);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ namespace skyline::service::settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result ISettingsServer::MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ISettingsServer::MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
response.Push<u64>(language::LanguageCodeList.at(request.Pop<i32>()));
|
response.Push<u64>(language::LanguageCodeList.at(static_cast<size_t>(request.Pop<i32>())));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,11 +24,11 @@ namespace skyline::service::timesrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constexpr TimeSpanType FromSeconds(i64 s) {
|
static constexpr TimeSpanType FromSeconds(i64 s) {
|
||||||
return {s * static_cast<i64>(skyline::constant::NsInSecond)};
|
return {s * skyline::constant::NsInSecond};
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr TimeSpanType FromDays(i64 d) {
|
static constexpr TimeSpanType FromDays(i64 d) {
|
||||||
return {d * static_cast<i64>(skyline::constant::NsInDay)};
|
return {d * skyline::constant::NsInDay};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr i64 Nanoseconds() const {
|
constexpr i64 Nanoseconds() const {
|
||||||
@ -36,11 +36,11 @@ namespace skyline::service::timesrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr i64 Microseconds() const {
|
constexpr i64 Microseconds() const {
|
||||||
return ns / static_cast<i64>(skyline::constant::NsInMicrosecond);
|
return ns / skyline::constant::NsInMicrosecond;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr i64 Seconds() const {
|
constexpr i64 Seconds() const {
|
||||||
return ns / static_cast<i64>(skyline::constant::NsInSecond);
|
return ns / skyline::constant::NsInSecond;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr friend bool operator>(const TimeSpanType &lhs, const TimeSpanType &rhs) {
|
constexpr friend bool operator>(const TimeSpanType &lhs, const TimeSpanType &rhs) {
|
||||||
|
@ -270,7 +270,7 @@ namespace skyline::service::timesrv::core {
|
|||||||
for (auto it{buffer.begin()}; it != buffer.end(); it++) {
|
for (auto it{buffer.begin()}; it != buffer.end(); it++) {
|
||||||
if (*it == '\n' && prev != it) {
|
if (*it == '\n' && prev != it) {
|
||||||
timesrv::LocationName name{};
|
timesrv::LocationName name{};
|
||||||
span(prev.base(), std::distance(prev, std::prev(it))).as_string().copy(name.data(), name.size());
|
span(prev.base(), static_cast<size_t>(std::distance(prev, std::prev(it)))).as_string().copy(name.data(), name.size());
|
||||||
locationNameList.push_back(name);
|
locationNameList.push_back(name);
|
||||||
|
|
||||||
if (std::next(it) != buffer.end())
|
if (std::next(it) != buffer.end())
|
||||||
@ -286,6 +286,6 @@ namespace skyline::service::timesrv::core {
|
|||||||
buffer.resize(timeZoneBinaryFile->size);
|
buffer.resize(timeZoneBinaryFile->size);
|
||||||
timeZoneBinaryFile->Read(buffer);
|
timeZoneBinaryFile->Read(buffer);
|
||||||
|
|
||||||
managerServer.SetupTimeZoneManager(state.os->deviceTimeZone, *timezoneUpdateTime, locationNameList.size(), timeZoneBinaryVersion, buffer);
|
managerServer.SetupTimeZoneManager(state.os->deviceTimeZone, *timezoneUpdateTime, static_cast<int>(locationNameList.size()), timeZoneBinaryVersion, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -33,7 +33,7 @@ namespace skyline::service::timesrv {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result TimeManagerServer::SetupTimeZoneManager(std::string_view locationName, const SteadyClockTimePoint &updateTime, size_t locationCount, std::array<u8, 0x10> binaryVersion, span<u8> binary) {
|
Result TimeManagerServer::SetupTimeZoneManager(std::string_view locationName, const SteadyClockTimePoint &updateTime, int locationCount, std::array<u8, 0x10> binaryVersion, span<u8> binary) {
|
||||||
return core.timeZoneManager.Setup(locationName, updateTime, locationCount, binaryVersion, binary);
|
return core.timeZoneManager.Setup(locationName, updateTime, locationCount, binaryVersion, binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ namespace skyline::service::timesrv {
|
|||||||
/**
|
/**
|
||||||
* @url https://switchbrew.org/w/index.php?title=PSC_services#SetupTimeZoneServiceCore
|
* @url https://switchbrew.org/w/index.php?title=PSC_services#SetupTimeZoneServiceCore
|
||||||
*/
|
*/
|
||||||
Result SetupTimeZoneManager(std::string_view locationName, const SteadyClockTimePoint &updateTime, size_t locationCount, std::array<u8, 0x10> binaryVersion, span<u8> binary);
|
Result SetupTimeZoneManager(std::string_view locationName, const SteadyClockTimePoint &updateTime, int locationCount, std::array<u8, 0x10> binaryVersion, span<u8> binary);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @url https://switchbrew.org/w/index.php?title=PSC_services#SetupEphemeralNetworkSystemClockCore
|
* @url https://switchbrew.org/w/index.php?title=PSC_services#SetupEphemeralNetworkSystemClockCore
|
||||||
|
@ -61,7 +61,7 @@ namespace skyline::service::timesrv::core {
|
|||||||
|
|
||||||
void TimeSharedMemory::SetupStandardSteadyClock(UUID rtcId, TimeSpanType baseTimePoint) {
|
void TimeSharedMemory::SetupStandardSteadyClock(UUID rtcId, TimeSpanType baseTimePoint) {
|
||||||
SteadyClockTimePoint context{
|
SteadyClockTimePoint context{
|
||||||
.timePoint = baseTimePoint.Nanoseconds() - static_cast<i64>(util::GetTimeNs()),
|
.timePoint = baseTimePoint.Nanoseconds() - util::GetTimeNs(),
|
||||||
.clockSourceId = rtcId
|
.clockSourceId = rtcId
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ namespace skyline::service::timesrv::core {
|
|||||||
|
|
||||||
void TimeSharedMemory::SetSteadyClockRawTimePoint(TimeSpanType timePoint) {
|
void TimeSharedMemory::SetSteadyClockRawTimePoint(TimeSpanType timePoint) {
|
||||||
auto context{ReadTimeSharedMemoryItem(timeSharedMemory->standardSteadyClockContextEntry.updateCount, timeSharedMemory->standardSteadyClockContextEntry.context)};
|
auto context{ReadTimeSharedMemoryItem(timeSharedMemory->standardSteadyClockContextEntry.updateCount, timeSharedMemory->standardSteadyClockContextEntry.context)};
|
||||||
context.timePoint = timePoint.Nanoseconds() - static_cast<i64>(util::GetTimeNs());
|
context.timePoint = timePoint.Nanoseconds() - util::GetTimeNs();
|
||||||
|
|
||||||
UpdateTimeSharedMemoryItem(timeSharedMemory->standardSteadyClockContextEntry.updateCount, timeSharedMemory->standardSteadyClockContextEntry.context, context);
|
UpdateTimeSharedMemoryItem(timeSharedMemory->standardSteadyClockContextEntry.updateCount, timeSharedMemory->standardSteadyClockContextEntry.context, context);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ namespace skyline::service::timesrv::core {
|
|||||||
Result TimeZoneManager::SetNewLocation(std::string_view pLocationName, span<u8> binary) {
|
Result TimeZoneManager::SetNewLocation(std::string_view pLocationName, span<u8> binary) {
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard lock(mutex);
|
||||||
|
|
||||||
rule = tz_tzalloc(binary.data(), binary.size());
|
rule = tz_tzalloc(binary.data(), static_cast<long>(binary.size()));
|
||||||
if (!rule)
|
if (!rule)
|
||||||
return result::RuleConversionFailed;
|
return result::RuleConversionFailed;
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ namespace skyline::service::timesrv::core {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result TimeZoneManager::ParseTimeZoneBinary(span<u8> binary, span<u8> ruleOut) {
|
Result TimeZoneManager::ParseTimeZoneBinary(span<u8> binary, span<u8> ruleOut) {
|
||||||
auto ruleObj{tz_tzalloc(binary.data(), binary.size())};
|
auto ruleObj{tz_tzalloc(binary.data(), static_cast<long>(binary.size()))};
|
||||||
if (!ruleObj)
|
if (!ruleObj)
|
||||||
return result::RuleConversionFailed;
|
return result::RuleConversionFailed;
|
||||||
|
|
||||||
|
@ -29,7 +29,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case Opcode::Operation::AddImmediate:
|
case Opcode::Operation::AddImmediate:
|
||||||
HandleAssignment(opcode->assignmentOperation, opcode->dest, registers[opcode->srcA] + opcode->immediate);
|
HandleAssignment(opcode->assignmentOperation, opcode->dest,
|
||||||
|
static_cast<u32>(static_cast<i32>(registers[opcode->srcA]) + opcode->immediate));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Opcode::Operation::BitfieldReplace: {
|
case Opcode::Operation::BitfieldReplace: {
|
||||||
@ -70,7 +71,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case Opcode::Operation::ReadImmediate: {
|
case Opcode::Operation::ReadImmediate: {
|
||||||
u32 result{maxwell3D.registers.raw[registers[opcode->srcA] + opcode->immediate]};
|
u32 result{maxwell3D.registers.raw[static_cast<size_t>(static_cast<i32>(registers[opcode->srcA]) + opcode->immediate)]};
|
||||||
HandleAssignment(opcode->assignmentOperation, opcode->dest, result);
|
HandleAssignment(opcode->assignmentOperation, opcode->dest, result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
if (!(method & 1)) {
|
if (!(method & 1)) {
|
||||||
if (macroInvocation.index != -1) {
|
if (macroInvocation.index != -1) {
|
||||||
// Flush the current macro as we are switching to another one
|
// Flush the current macro as we are switching to another one
|
||||||
macroInterpreter.Execute(macroPositions[macroInvocation.index], macroInvocation.arguments);
|
macroInterpreter.Execute(macroPositions[static_cast<size_t>(macroInvocation.index)], macroInvocation.arguments);
|
||||||
macroInvocation.arguments.clear();
|
macroInvocation.arguments.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
// Flush macro after all of the data in the method call has been sent
|
// Flush macro after all of the data in the method call has been sent
|
||||||
if (lastCall && macroInvocation.index != -1) {
|
if (lastCall && macroInvocation.index != -1) {
|
||||||
macroInterpreter.Execute(macroPositions[macroInvocation.index], macroInvocation.arguments);
|
macroInterpreter.Execute(macroPositions[static_cast<size_t>(macroInvocation.index)], macroInvocation.arguments);
|
||||||
macroInvocation.arguments.clear();
|
macroInvocation.arguments.clear();
|
||||||
macroInvocation.index = -1;
|
macroInvocation.index = -1;
|
||||||
}
|
}
|
||||||
@ -313,13 +313,14 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
case type::SemaphoreInfo::StructureSize::FourWords: {
|
case type::SemaphoreInfo::StructureSize::FourWords: {
|
||||||
// Convert the current nanosecond time to GPU ticks
|
// Convert the current nanosecond time to GPU ticks
|
||||||
constexpr u64 NsToTickNumerator{384};
|
constexpr i64 NsToTickNumerator{384};
|
||||||
constexpr u64 NsToTickDenominator{625};
|
constexpr i64 NsToTickDenominator{625};
|
||||||
|
|
||||||
u64 nsTime{util::GetTimeNs()};
|
i64 nsTime{util::GetTimeNs()};
|
||||||
u64 timestamp{(nsTime / NsToTickDenominator) * NsToTickNumerator + ((nsTime % NsToTickDenominator) * NsToTickNumerator) / NsToTickDenominator};
|
i64 timestamp{(nsTime / NsToTickDenominator) * NsToTickNumerator + ((nsTime % NsToTickDenominator) * NsToTickNumerator) / NsToTickDenominator};
|
||||||
|
|
||||||
channelCtx.asCtx->gmmu.Write<FourWordResult>(registers.semaphore.address.Pack(), FourWordResult{result, timestamp});
|
channelCtx.asCtx->gmmu.Write<FourWordResult>(registers.semaphore.address.Pack(),
|
||||||
|
FourWordResult{result, static_cast<u64>(timestamp)});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ namespace skyline::vfs {
|
|||||||
if (mode.write || mode.append)
|
if (mode.write || mode.append)
|
||||||
throw exception("AndroidAssetBacking doesn't support writing");
|
throw exception("AndroidAssetBacking doesn't support writing");
|
||||||
|
|
||||||
size = AAsset_getLength64(asset);
|
size = static_cast<size_t>(AAsset_getLength64(asset));
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidAssetBacking::~AndroidAssetBacking() {
|
AndroidAssetBacking::~AndroidAssetBacking() {
|
||||||
@ -18,7 +18,7 @@ namespace skyline::vfs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t AndroidAssetBacking::ReadImpl(span<u8> output, size_t offset) {
|
size_t AndroidAssetBacking::ReadImpl(span<u8> output, size_t offset) {
|
||||||
if (AAsset_seek64(asset, offset, SEEK_SET) != offset)
|
if (AAsset_seek64(asset, static_cast<off64_t>(offset), SEEK_SET) != offset)
|
||||||
throw exception("Failed to seek asset position");
|
throw exception("Failed to seek asset position");
|
||||||
|
|
||||||
auto result{AAsset_read(asset, output.data(), output.size())};
|
auto result{AAsset_read(asset, output.data(), output.size())};
|
||||||
|
@ -110,7 +110,7 @@ namespace skyline::vfs {
|
|||||||
if (!mode.write)
|
if (!mode.write)
|
||||||
throw exception("Attempting to write to a backing that is not writable");
|
throw exception("Attempting to write to a backing that is not writable");
|
||||||
|
|
||||||
if (input.size() > (static_cast<ssize_t>(size) - offset)) {
|
if (input.size() > (static_cast<ssize_t>(size) - static_cast<ssize_t>(offset))) {
|
||||||
if (mode.append)
|
if (mode.append)
|
||||||
Resize(offset + input.size());
|
Resize(offset + input.size());
|
||||||
else
|
else
|
||||||
|
@ -54,7 +54,8 @@ namespace skyline::vfs {
|
|||||||
auto trailingOnes{std::countr_zero(~capability.raw)};
|
auto trailingOnes{std::countr_zero(~capability.raw)};
|
||||||
switch (trailingOnes) {
|
switch (trailingOnes) {
|
||||||
case 3:
|
case 3:
|
||||||
threadInfo.priority = kernel::Priority{capability.threadInfo.highestPriority, capability.threadInfo.lowestPriority};
|
threadInfo.priority = kernel::Priority{static_cast<i8>(capability.threadInfo.highestPriority),
|
||||||
|
static_cast<i8>(capability.threadInfo.lowestPriority)};
|
||||||
|
|
||||||
threadInfo.coreMask = {};
|
threadInfo.coreMask = {};
|
||||||
for (u8 core{capability.threadInfo.minCoreId}; core <= capability.threadInfo.maxCoreId; core++)
|
for (u8 core{capability.threadInfo.minCoreId}; core <= capability.threadInfo.maxCoreId; core++)
|
||||||
|
@ -44,7 +44,7 @@ namespace skyline {
|
|||||||
u8 raw{};
|
u8 raw{};
|
||||||
} flags;
|
} flags;
|
||||||
u8 _unk1_;
|
u8 _unk1_;
|
||||||
u8 mainThreadPriority;
|
i8 mainThreadPriority;
|
||||||
u8 idealCore;
|
u8 idealCore;
|
||||||
u32 _unk2_;
|
u32 _unk2_;
|
||||||
u32 systemResourceSize; //!< 3.0.0+
|
u32 systemResourceSize; //!< 3.0.0+
|
||||||
|
@ -12,7 +12,7 @@ namespace skyline::vfs {
|
|||||||
if (fstat(fd, &fileInfo))
|
if (fstat(fd, &fileInfo))
|
||||||
throw exception("Failed to stat fd: {}", strerror(errno));
|
throw exception("Failed to stat fd: {}", strerror(errno));
|
||||||
|
|
||||||
size = fileInfo.st_size;
|
size = static_cast<size_t>(fileInfo.st_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
OsBacking::~OsBacking() {
|
OsBacking::~OsBacking() {
|
||||||
@ -21,7 +21,7 @@ namespace skyline::vfs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t OsBacking::ReadImpl(span<u8> output, size_t offset) {
|
size_t OsBacking::ReadImpl(span<u8> output, size_t offset) {
|
||||||
auto ret{pread64(fd, output.data(), output.size(), offset)};
|
auto ret{pread64(fd, output.data(), output.size(), static_cast<off64_t>(offset))};
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
throw exception("Failed to read from fd: {}", strerror(errno));
|
throw exception("Failed to read from fd: {}", strerror(errno));
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ namespace skyline::vfs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t OsBacking::WriteImpl(span<u8> input, size_t offset) {
|
size_t OsBacking::WriteImpl(span<u8> input, size_t offset) {
|
||||||
auto ret{pwrite64(fd, input.data(), input.size(), offset)};
|
auto ret{pwrite64(fd, input.data(), input.size(), static_cast<off64_t>(offset))};
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
throw exception("Failed to write to fd: {}", strerror(errno));
|
throw exception("Failed to write to fd: {}", strerror(errno));
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ namespace skyline::vfs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OsBacking::ResizeImpl(size_t pSize) {
|
void OsBacking::ResizeImpl(size_t pSize) {
|
||||||
int ret{ftruncate(fd, pSize)};
|
int ret{ftruncate(fd, static_cast<off_t>(pSize))};
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
throw exception("Failed to resize file: {}", strerror(errno));
|
throw exception("Failed to resize file: {}", strerror(errno));
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ namespace skyline::vfs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Truncate the file to desired length
|
// Truncate the file to desired length
|
||||||
int ret{ftruncate(fd, size)};
|
int ret{ftruncate(fd, static_cast<off_t>(size))};
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user