mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 17:41:47 +01:00
Equal -> Brace Initializer + Remove Constexpr Auto for Integers
This commit is contained in:
parent
2764bd7c96
commit
429af1990a
@ -42,14 +42,14 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
|||||||
|
|
||||||
setpriority(PRIO_PROCESS, static_cast<id_t>(gettid()), -8); // Set the priority of this process to the highest value
|
setpriority(PRIO_PROCESS, static_cast<id_t>(gettid()), -8); // Set the priority of this process to the highest value
|
||||||
|
|
||||||
auto jvmManager = std::make_shared<skyline::JvmManager>(env, instance);
|
auto jvmManager{std::make_shared<skyline::JvmManager>(env, instance)};
|
||||||
auto settings = std::make_shared<skyline::Settings>(preferenceFd);
|
auto settings{std::make_shared<skyline::Settings>(preferenceFd)};
|
||||||
|
|
||||||
auto appFilesPath = env->GetStringUTFChars(appFilesPathJstring, nullptr);
|
auto appFilesPath{env->GetStringUTFChars(appFilesPathJstring, nullptr)};
|
||||||
auto logger = std::make_shared<skyline::Logger>(std::string(appFilesPath) + "skyline.log", static_cast<skyline::Logger::LogLevel>(std::stoi(settings->GetString("log_level"))));
|
auto logger{std::make_shared<skyline::Logger>(std::string(appFilesPath) + "skyline.log", static_cast<skyline::Logger::LogLevel>(std::stoi(settings->GetString("log_level"))))};
|
||||||
//settings->List(logger); // (Uncomment when you want to print out all settings strings)
|
//settings->List(logger); // (Uncomment when you want to print out all settings strings)
|
||||||
|
|
||||||
auto start = std::chrono::steady_clock::now();
|
auto start{std::chrono::steady_clock::now()};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
skyline::kernel::OS os(jvmManager, logger, settings, std::string(appFilesPath));
|
skyline::kernel::OS os(jvmManager, logger, settings, std::string(appFilesPath));
|
||||||
@ -57,7 +57,7 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
|||||||
jvmManager->InitializeControllers();
|
jvmManager->InitializeControllers();
|
||||||
env->ReleaseStringUTFChars(appFilesPathJstring, appFilesPath);
|
env->ReleaseStringUTFChars(appFilesPathJstring, appFilesPath);
|
||||||
|
|
||||||
auto romUri = env->GetStringUTFChars(romUriJstring, nullptr);
|
auto romUri{env->GetStringUTFChars(romUriJstring, nullptr)};
|
||||||
logger->Info("Launching ROM {}", romUri);
|
logger->Info("Launching ROM {}", romUri);
|
||||||
env->ReleaseStringUTFChars(romUriJstring, romUri);
|
env->ReleaseStringUTFChars(romUriJstring, romUri);
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
|
|||||||
|
|
||||||
logger->Info("Emulation has ended");
|
logger->Info("Emulation has ended");
|
||||||
|
|
||||||
auto end = std::chrono::steady_clock::now();
|
auto end{std::chrono::steady_clock::now()};
|
||||||
logger->Info("Done in: {} ms", (std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()));
|
logger->Info("Done in: {} ms", (std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ extern "C" JNIEXPORT jfloat Java_emu_skyline_EmulationActivity_getFrametime(JNIE
|
|||||||
}
|
}
|
||||||
|
|
||||||
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[index] = skyline::input::GuestController{static_cast<skyline::input::NpadControllerType>(type), static_cast<skyline::i8>(partnerIndex)};
|
||||||
}
|
}
|
||||||
@ -113,8 +113,8 @@ extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_updateContr
|
|||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setButtonState(JNIEnv *, jobject, jint index, jlong mask, jboolean pressed) {
|
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setButtonState(JNIEnv *, jobject, jint index, jlong mask, jboolean pressed) {
|
||||||
try {
|
try {
|
||||||
auto input = inputWeak.lock();
|
auto input{inputWeak.lock()};
|
||||||
auto device = input->npad.controllers[index].device;
|
auto device{input->npad.controllers[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);
|
||||||
} catch (const std::bad_weak_ptr &) {
|
} catch (const std::bad_weak_ptr &) {
|
||||||
@ -124,8 +124,8 @@ extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setButtonSt
|
|||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setAxisValue(JNIEnv *, jobject, jint index, jint axis, jint value) {
|
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setAxisValue(JNIEnv *, jobject, jint index, jint axis, jint value) {
|
||||||
try {
|
try {
|
||||||
auto input = inputWeak.lock();
|
auto input{inputWeak.lock()};
|
||||||
auto device = input->npad.controllers[index].device;
|
auto device{input->npad.controllers[index].device};
|
||||||
if (device)
|
if (device)
|
||||||
device->SetAxisValue(static_cast<skyline::input::NpadAxisId>(axis), value);
|
device->SetAxisValue(static_cast<skyline::input::NpadAxisId>(axis), value);
|
||||||
} catch (const std::bad_weak_ptr &) {
|
} catch (const std::bad_weak_ptr &) {
|
||||||
@ -137,7 +137,7 @@ extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setTouchSta
|
|||||||
try {
|
try {
|
||||||
using Point = skyline::input::TouchScreenPoint;
|
using Point = skyline::input::TouchScreenPoint;
|
||||||
|
|
||||||
auto input = inputWeak.lock();
|
auto input{inputWeak.lock()};
|
||||||
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)), env->GetArrayLength(pointsJni) / (sizeof(Point) / sizeof(jint)));
|
||||||
|
@ -46,9 +46,9 @@ namespace skyline::audio {
|
|||||||
|
|
||||||
std::lock_guard bufferGuard(track->bufferLock);
|
std::lock_guard bufferGuard(track->bufferLock);
|
||||||
|
|
||||||
auto trackSamples = track->samples.Read(destBuffer, streamSamples, [](i16 *source, i16 *destination) {
|
auto trackSamples{track->samples.Read(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);
|
}, writtenSamples)};
|
||||||
|
|
||||||
writtenSamples = std::max(trackSamples, writtenSamples);
|
writtenSamples = std::max(trackSamples, writtenSamples);
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ namespace skyline::audio {
|
|||||||
|
|
||||||
i32 ctx{};
|
i32 ctx{};
|
||||||
|
|
||||||
for (size_t index = 0; index < frameSamples; index++) {
|
for (size_t index{}; index < frameSamples; index++) {
|
||||||
i32 sample{};
|
i32 sample{};
|
||||||
|
|
||||||
if (index & 1) {
|
if (index & 1) {
|
||||||
@ -35,10 +35,10 @@ namespace skyline::audio {
|
|||||||
sample = (ctx << 24) >> 28;
|
sample = (ctx << 24) >> 28;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 prediction = history[0] * coefficients[header.coefficientIndex][0] + history[1] * coefficients[header.coefficientIndex][1];
|
i32 prediction{history[0] * coefficients[header.coefficientIndex][0] + history[1] * coefficients[header.coefficientIndex][1]};
|
||||||
sample = (sample * (0x800 << header.scale) + prediction + 0x400) >> 11;
|
sample = (sample * (0x800 << header.scale) + prediction + 0x400) >> 11;
|
||||||
|
|
||||||
auto saturated = audio::Saturate<i16, i32>(sample);
|
auto saturated{audio::Saturate<i16, i32>(sample)};
|
||||||
output.push_back(saturated);
|
output.push_back(saturated);
|
||||||
history[1] = history[0];
|
history[1] = history[0];
|
||||||
history[0] = saturated;
|
history[0] = saturated;
|
||||||
|
@ -48,9 +48,9 @@ namespace skyline::audio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (copyFunction && copyOffset) {
|
if (copyFunction && copyOffset) {
|
||||||
auto sourceEnd = start + ((copyOffset != -1) ? copyOffset : sizeEnd);
|
auto sourceEnd{start + ((copyOffset != -1) ? copyOffset : sizeEnd)};
|
||||||
|
|
||||||
for (auto source = start, destination = address; source < sourceEnd; source++, destination++)
|
for (auto source{start}, destination{address}; source < sourceEnd; source++, destination++)
|
||||||
copyFunction(source, destination);
|
copyFunction(source, destination);
|
||||||
|
|
||||||
if (copyOffset != -1) {
|
if (copyOffset != -1) {
|
||||||
@ -65,9 +65,9 @@ namespace skyline::audio {
|
|||||||
|
|
||||||
if (sizeBegin) {
|
if (sizeBegin) {
|
||||||
if (copyFunction && copyOffset) {
|
if (copyFunction && copyOffset) {
|
||||||
auto sourceEnd = array.begin() + ((copyOffset != -1) ? copyOffset : sizeBegin);
|
auto sourceEnd{array.begin() + ((copyOffset != -1) ? copyOffset : sizeBegin)};
|
||||||
|
|
||||||
for (auto source = array.begin(), destination = address; source < sourceEnd; source++, destination++)
|
for (auto source{array.begin()}, destination{address}; source < sourceEnd; source++, destination++)
|
||||||
copyFunction(source, destination);
|
copyFunction(source, destination);
|
||||||
|
|
||||||
if (copyOffset != -1)
|
if (copyOffset != -1)
|
||||||
@ -97,7 +97,7 @@ namespace skyline::audio {
|
|||||||
|
|
||||||
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, address, sizeEnd * sizeof(Type));
|
std::memcpy(end, address, sizeEnd * sizeof(Type));
|
||||||
|
|
||||||
address += sizeEnd;
|
address += sizeEnd;
|
||||||
@ -105,8 +105,8 @@ namespace skyline::audio {
|
|||||||
|
|
||||||
end += sizeEnd;
|
end += sizeEnd;
|
||||||
} else {
|
} else {
|
||||||
auto sizePreStart = (end == array.end()) ? std::min(start - array.begin(), size) : std::min(start - end, size);
|
auto sizePreStart{(end == array.end()) ? std::min(start - array.begin(), size) : std::min(start - end, size)};
|
||||||
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, address, sizePreStart * sizeof(Type));
|
std::memcpy((end == array.end()) ? array.begin() : end, address, sizePreStart * sizeof(Type));
|
||||||
|
@ -137,10 +137,10 @@ namespace skyline::audio {
|
|||||||
u32 lutIndex{fraction >> 8};
|
u32 lutIndex{fraction >> 8};
|
||||||
|
|
||||||
for (u8 channel{}; channel < channelCount; channel++) {
|
for (u8 channel{}; channel < channelCount; channel++) {
|
||||||
i32 data = inputBuffer[(inIndex + 0) * channelCount + channel] * lut[lutIndex].a +
|
i32 data{inputBuffer[(inIndex + 0) * channelCount + channel] * lut[lutIndex].a +
|
||||||
inputBuffer[(inIndex + 1) * channelCount + channel] * lut[lutIndex].b +
|
inputBuffer[(inIndex + 1) * channelCount + channel] * lut[lutIndex].b +
|
||||||
inputBuffer[(inIndex + 2) * channelCount + channel] * lut[lutIndex].c +
|
inputBuffer[(inIndex + 2) * channelCount + channel] * lut[lutIndex].c +
|
||||||
inputBuffer[(inIndex + 3) * channelCount + channel] * lut[lutIndex].d;
|
inputBuffer[(inIndex + 3) * channelCount + channel] * lut[lutIndex].d};
|
||||||
|
|
||||||
outputBuffer[outIndex + channel] = Saturate<i16, i32>(data >> 15);
|
outputBuffer[outIndex + channel] = Saturate<i16, i32>(data >> 15);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ namespace skyline::audio {
|
|||||||
|
|
||||||
bool AudioTrack::ContainsBuffer(u64 tag) {
|
bool AudioTrack::ContainsBuffer(u64 tag) {
|
||||||
// Iterate from front of queue as we don't want released samples
|
// Iterate from front of queue as we don't want released samples
|
||||||
for (auto identifier = identifiers.crbegin(); identifier != identifiers.crend(); identifier++) {
|
for (auto identifier{identifiers.crbegin()}; identifier != identifiers.crend(); identifier++) {
|
||||||
if (identifier->released)
|
if (identifier->released)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
namespace skyline {
|
namespace skyline {
|
||||||
void Mutex::lock() {
|
void Mutex::lock() {
|
||||||
while (true) {
|
while (true) {
|
||||||
for (int i = 0; i < 1000; ++i) {
|
for (int i{}; i < 1000; ++i) {
|
||||||
if (!flag.test_and_set(std::memory_order_acquire))
|
if (!flag.test_and_set(std::memory_order_acquire))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -23,9 +23,9 @@ namespace skyline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GroupMutex::lock(Group group) {
|
void GroupMutex::lock(Group group) {
|
||||||
auto none = Group::None;
|
auto none{Group::None};
|
||||||
constexpr u64 timeout = 100; // The timeout in ns
|
constexpr u64 timeout{100}; // The timeout in ns
|
||||||
auto end = util::GetTimeNs() + timeout;
|
auto end{util::GetTimeNs() + timeout};
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (next == group) {
|
if (next == group) {
|
||||||
@ -33,7 +33,7 @@ namespace skyline {
|
|||||||
std::lock_guard lock(mtx);
|
std::lock_guard lock(mtx);
|
||||||
|
|
||||||
if (flag == group) {
|
if (flag == group) {
|
||||||
auto groupT = group;
|
auto groupT{group};
|
||||||
next.compare_exchange_strong(groupT, Group::None);
|
next.compare_exchange_strong(groupT, Group::None);
|
||||||
num++;
|
num++;
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ namespace skyline {
|
|||||||
if (pref.LoadFile(fdopen(fd, "r")))
|
if (pref.LoadFile(fdopen(fd, "r")))
|
||||||
throw exception("TinyXML2 Error: " + std::string(pref.ErrorStr()));
|
throw exception("TinyXML2 Error: " + std::string(pref.ErrorStr()));
|
||||||
|
|
||||||
tinyxml2::XMLElement *elem = pref.LastChild()->FirstChild()->ToElement();
|
tinyxml2::XMLElement *elem{pref.LastChild()->FirstChild()->ToElement()};
|
||||||
|
|
||||||
while (elem) {
|
while (elem) {
|
||||||
switch (elem->Value()[0]) {
|
switch (elem->Value()[0]) {
|
||||||
|
@ -57,15 +57,15 @@ namespace skyline {
|
|||||||
|
|
||||||
namespace constant {
|
namespace constant {
|
||||||
// Memory
|
// Memory
|
||||||
constexpr u64 BaseAddress = 0x8000000; //!< The address space base
|
constexpr u64 BaseAddress{0x8000000}; //!< The address space base
|
||||||
constexpr u64 DefStackSize = 0x1E8480; //!< The default amount of stack: 2 MB
|
constexpr u64 DefStackSize{0x1E8480}; //!< The default amount of stack: 2 MB
|
||||||
// Display
|
// Display
|
||||||
constexpr u16 HandheldResolutionW = 1280; //!< The width component of the handheld resolution
|
constexpr u16 HandheldResolutionW{1280}; //!< The width component of the handheld resolution
|
||||||
constexpr u16 HandheldResolutionH = 720; //!< The height component of the handheld resolution
|
constexpr u16 HandheldResolutionH{720}; //!< The height component of the handheld resolution
|
||||||
constexpr u16 DockedResolutionW = 1920; //!< The width component of the docked resolution
|
constexpr u16 DockedResolutionW{1920}; //!< The width component of the docked resolution
|
||||||
constexpr u16 DockedResolutionH = 1080; //!< The height component of the docked resolution
|
constexpr u16 DockedResolutionH{1080}; //!< The height component of the docked resolution
|
||||||
// Time
|
// Time
|
||||||
constexpr u64 NsInSecond = 1000000000; //!< This is the amount of nanoseconds in a second
|
constexpr u64 NsInSecond{1000000000}; //!< This is the amount of nanoseconds in a second
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,7 +156,7 @@ namespace skyline {
|
|||||||
template<typename Type>
|
template<typename Type>
|
||||||
constexpr Type MakeMagic(std::string_view string) {
|
constexpr Type MakeMagic(std::string_view string) {
|
||||||
Type object{};
|
Type object{};
|
||||||
auto offset = 0;
|
size_t offset{};
|
||||||
|
|
||||||
for (auto &character : string) {
|
for (auto &character : string) {
|
||||||
object |= static_cast<Type>(character) << offset;
|
object |= static_cast<Type>(character) << offset;
|
||||||
@ -356,7 +356,7 @@ namespace skyline {
|
|||||||
private:
|
private:
|
||||||
std::atomic<Group> flag{Group::None}; //!< An atomic flag to hold which group holds the mutex
|
std::atomic<Group> flag{Group::None}; //!< An atomic flag to hold which group holds the mutex
|
||||||
std::atomic<Group> next{Group::None}; //!< An atomic flag to hold which group will hold the mutex next
|
std::atomic<Group> next{Group::None}; //!< An atomic flag to hold which group will hold the mutex next
|
||||||
std::atomic<u8> num{0}; //!< An atomic u8 keeping track of how many users are holding the mutex
|
std::atomic<u8> num{}; //!< An atomic u8 keeping track of how many users are holding the mutex
|
||||||
Mutex mtx; //!< A mutex to lock before changing of num and flag
|
Mutex mtx; //!< A mutex to lock before changing of num and flag
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,9 +23,10 @@ namespace skyline::crypto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AesCipher::Decrypt(u8 *destination, u8 *source, size_t size) {
|
void AesCipher::Decrypt(u8 *destination, u8 *source, size_t size) {
|
||||||
std::optional<std::vector<u8>> buf{};
|
constexpr size_t maxBufferSize = 1024 * 1024; //!< Buffer shouldn't grow larger than 1 MiB
|
||||||
|
|
||||||
u8 *targetDestination = [&]() {
|
std::optional<std::vector<u8>> buf{};
|
||||||
|
u8 *targetDestination{[&]() {
|
||||||
if (destination == source) {
|
if (destination == source) {
|
||||||
if (size > maxBufferSize) {
|
if (size > maxBufferSize) {
|
||||||
buf.emplace(size);
|
buf.emplace(size);
|
||||||
@ -37,7 +38,7 @@ namespace skyline::crypto {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return destination;
|
return destination;
|
||||||
}();
|
}()};
|
||||||
|
|
||||||
mbedtls_cipher_reset(&decryptContext);
|
mbedtls_cipher_reset(&decryptContext);
|
||||||
|
|
||||||
|
@ -14,11 +14,6 @@ namespace skyline::crypto {
|
|||||||
private:
|
private:
|
||||||
mbedtls_cipher_context_t decryptContext;
|
mbedtls_cipher_context_t decryptContext;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Buffer should grow bigger than 1 MiB
|
|
||||||
*/
|
|
||||||
static constexpr size_t maxBufferSize = 1024 * 1024;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Buffer declared as class variable to avoid constant memory allocation
|
* @brief Buffer declared as class variable to avoid constant memory allocation
|
||||||
*/
|
*/
|
||||||
|
@ -49,7 +49,7 @@ namespace skyline::crypto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (keyName.size() > 2) {
|
if (keyName.size() > 2) {
|
||||||
auto it = indexedKey128Names.find(keyName.substr(0, keyName.size() - 2));
|
auto it{indexedKey128Names.find(keyName.substr(0, keyName.size() - 2))};
|
||||||
if (it != indexedKey128Names.end()) {
|
if (it != indexedKey128Names.end()) {
|
||||||
size_t index{std::stoul(std::string(keyName.substr(it->first.size())), nullptr, 16)};
|
size_t index{std::stoul(std::string(keyName.substr(it->first.size())), nullptr, 16)};
|
||||||
it->second[index] = util::HexStringToArray<16>(value);
|
it->second[index] = util::HexStringToArray<16>(value);
|
||||||
|
@ -43,10 +43,10 @@ namespace skyline::gpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!presentationQueue.empty()) {
|
if (!presentationQueue.empty()) {
|
||||||
auto &texture = presentationQueue.front();
|
auto &texture{presentationQueue.front()};
|
||||||
presentationQueue.pop();
|
presentationQueue.pop();
|
||||||
|
|
||||||
auto textureFormat = texture->GetAndroidFormat();
|
auto textureFormat{texture->GetAndroidFormat()};
|
||||||
if (resolution != texture->dimensions || textureFormat != format) {
|
if (resolution != texture->dimensions || textureFormat != format) {
|
||||||
ANativeWindow_setBuffersGeometry(window, texture->dimensions.width, texture->dimensions.height, textureFormat);
|
ANativeWindow_setBuffersGeometry(window, texture->dimensions.width, texture->dimensions.height, textureFormat);
|
||||||
resolution = texture->dimensions;
|
resolution = texture->dimensions;
|
||||||
@ -64,7 +64,7 @@ namespace skyline::gpu {
|
|||||||
texture->releaseCallback();
|
texture->releaseCallback();
|
||||||
|
|
||||||
if (frameTimestamp) {
|
if (frameTimestamp) {
|
||||||
auto now = util::GetTimeNs();
|
auto now{util::GetTimeNs()};
|
||||||
|
|
||||||
frametime = static_cast<u32>((now - frameTimestamp) / 10000); // frametime / 100 is the real ms value, this is to retain the first two decimals
|
frametime = static_cast<u32>((now - frameTimestamp) / 10000); // frametime / 100 is the real ms value, this is to retain the first two decimals
|
||||||
fps = static_cast<u16>(constant::NsInSecond / (now - frameTimestamp));
|
fps = static_cast<u16>(constant::NsInSecond / (now - frameTimestamp));
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr u32 GpfifoRegisterCount = 0x40; //!< The number of GPFIFO registers
|
constexpr u32 GpfifoRegisterCount{0x40}; //!< The number of GPFIFO registers
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace gpu::engine {
|
namespace gpu::engine {
|
||||||
|
@ -161,11 +161,11 @@ namespace skyline::gpu::engine {
|
|||||||
break;
|
break;
|
||||||
case Registers::SemaphoreInfo::StructureSize::FourWords: {
|
case Registers::SemaphoreInfo::StructureSize::FourWords: {
|
||||||
// Convert the current nanosecond time to GPU ticks
|
// Convert the current nanosecond time to GPU ticks
|
||||||
constexpr u64 NsToTickNumerator = 384;
|
constexpr u64 NsToTickNumerator{384};
|
||||||
constexpr u64 NsToTickDenominator = 625;
|
constexpr u64 NsToTickDenominator{625};
|
||||||
|
|
||||||
u64 nsTime = util::GetTimeNs();
|
u64 nsTime{util::GetTimeNs()};
|
||||||
u64 timestamp = (nsTime / NsToTickDenominator) * NsToTickNumerator + ((nsTime % NsToTickDenominator) * NsToTickNumerator) / NsToTickDenominator;
|
u64 timestamp{(nsTime / NsToTickDenominator) * NsToTickNumerator + ((nsTime % NsToTickDenominator) * NsToTickNumerator) / NsToTickDenominator};
|
||||||
|
|
||||||
state.gpu->memoryManager.Write<FourWordResult>(FourWordResult{result, timestamp}, registers.semaphore.address.Pack());
|
state.gpu->memoryManager.Write<FourWordResult>(FourWordResult{result, timestamp}, registers.semaphore.address.Pack());
|
||||||
break;
|
break;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr u32 Maxwell3DRegisterCounter = 0xE00; //!< The number of Maxwell 3D registers
|
constexpr u32 Maxwell3DRegisterCounter{0xE00}; //!< The number of Maxwell 3D registers
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace gpu::engine {
|
namespace gpu::engine {
|
||||||
|
@ -43,12 +43,12 @@ namespace skyline::gpu::gpfifo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GPFIFO::Process(const std::vector<u32> &segment) {
|
void GPFIFO::Process(const std::vector<u32> &segment) {
|
||||||
for (auto entry = segment.begin(); entry != segment.end(); entry++) {
|
for (auto entry{segment.begin()}; entry != segment.end(); entry++) {
|
||||||
// An entry containing all zeroes is a NOP, skip over it
|
// An entry containing all zeroes is a NOP, skip over it
|
||||||
if (*entry == 0)
|
if (*entry == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto methodHeader = reinterpret_cast<const PushBufferMethodHeader *>(&*entry);
|
auto methodHeader{reinterpret_cast<const PushBufferMethodHeader *>(&*entry)};
|
||||||
|
|
||||||
switch (methodHeader->secOp) {
|
switch (methodHeader->secOp) {
|
||||||
case PushBufferMethodHeader::SecOp::IncMethod:
|
case PushBufferMethodHeader::SecOp::IncMethod:
|
||||||
@ -80,7 +80,7 @@ namespace skyline::gpu::gpfifo {
|
|||||||
void GPFIFO::Run() {
|
void GPFIFO::Run() {
|
||||||
std::lock_guard lock(pushBufferQueueLock);
|
std::lock_guard lock(pushBufferQueueLock);
|
||||||
while (!pushBufferQueue.empty()) {
|
while (!pushBufferQueue.empty()) {
|
||||||
auto pushBuffer = pushBufferQueue.front();
|
auto pushBuffer{pushBufferQueue.front()};
|
||||||
if (pushBuffer.segment.empty())
|
if (pushBuffer.segment.empty())
|
||||||
pushBuffer.Fetch(state.gpu->memoryManager);
|
pushBuffer.Fetch(state.gpu->memoryManager);
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ namespace skyline::gpu {
|
|||||||
FORCE_INLINE bool MacroInterpreter::Step(Opcode *delayedOpcode) {
|
FORCE_INLINE bool MacroInterpreter::Step(Opcode *delayedOpcode) {
|
||||||
switch (opcode->operation) {
|
switch (opcode->operation) {
|
||||||
case Opcode::Operation::AluRegister: {
|
case Opcode::Operation::AluRegister: {
|
||||||
u32 result = HandleAlu(opcode->aluOperation, registers[opcode->srcA], registers[opcode->srcB]);
|
u32 result{HandleAlu(opcode->aluOperation, registers[opcode->srcA], registers[opcode->srcB])};
|
||||||
|
|
||||||
HandleAssignment(opcode->assignmentOperation, opcode->dest, result);
|
HandleAssignment(opcode->assignmentOperation, opcode->dest, result);
|
||||||
break;
|
break;
|
||||||
@ -32,8 +32,8 @@ namespace skyline::gpu {
|
|||||||
HandleAssignment(opcode->assignmentOperation, opcode->dest, registers[opcode->srcA] + opcode->immediate);
|
HandleAssignment(opcode->assignmentOperation, opcode->dest, registers[opcode->srcA] + opcode->immediate);
|
||||||
break;
|
break;
|
||||||
case Opcode::Operation::BitfieldReplace: {
|
case Opcode::Operation::BitfieldReplace: {
|
||||||
u32 src = registers[opcode->srcB];
|
u32 src{registers[opcode->srcB]};
|
||||||
u32 dest = registers[opcode->srcA];
|
u32 dest{registers[opcode->srcA]};
|
||||||
|
|
||||||
// Extract the source region
|
// Extract the source region
|
||||||
src = (src >> opcode->bitfield.srcBit) & opcode->bitfield.GetMask();
|
src = (src >> opcode->bitfield.srcBit) & opcode->bitfield.GetMask();
|
||||||
@ -48,25 +48,25 @@ namespace skyline::gpu {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Opcode::Operation::BitfieldExtractShiftLeftImmediate: {
|
case Opcode::Operation::BitfieldExtractShiftLeftImmediate: {
|
||||||
u32 src = registers[opcode->srcB];
|
u32 src{registers[opcode->srcB]};
|
||||||
u32 dest = registers[opcode->srcA];
|
u32 dest{registers[opcode->srcA]};
|
||||||
|
|
||||||
u32 result = ((src >> dest) & opcode->bitfield.GetMask()) << opcode->bitfield.destBit;
|
u32 result{((src >> dest) & opcode->bitfield.GetMask()) << opcode->bitfield.destBit};
|
||||||
|
|
||||||
HandleAssignment(opcode->assignmentOperation, opcode->dest, result);
|
HandleAssignment(opcode->assignmentOperation, opcode->dest, result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Opcode::Operation::BitfieldExtractShiftLeftRegister: {
|
case Opcode::Operation::BitfieldExtractShiftLeftRegister: {
|
||||||
u32 src = registers[opcode->srcB];
|
u32 src{registers[opcode->srcB]};
|
||||||
u32 dest = registers[opcode->srcA];
|
u32 dest{registers[opcode->srcA]};
|
||||||
|
|
||||||
u32 result = ((src >> opcode->bitfield.srcBit) & opcode->bitfield.GetMask()) << dest;
|
u32 result{((src >> opcode->bitfield.srcBit) & opcode->bitfield.GetMask()) << dest};
|
||||||
|
|
||||||
HandleAssignment(opcode->assignmentOperation, opcode->dest, result);
|
HandleAssignment(opcode->assignmentOperation, opcode->dest, result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Opcode::Operation::ReadImmediate: {
|
case Opcode::Operation::ReadImmediate: {
|
||||||
u32 result = maxwell3D.registers.raw[registers[opcode->srcA] + opcode->immediate];
|
u32 result{maxwell3D.registers.raw[registers[opcode->srcA] + opcode->immediate]};
|
||||||
HandleAssignment(opcode->assignmentOperation, opcode->dest, result);
|
HandleAssignment(opcode->assignmentOperation, opcode->dest, result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -74,15 +74,15 @@ namespace skyline::gpu {
|
|||||||
if (delayedOpcode != nullptr)
|
if (delayedOpcode != nullptr)
|
||||||
throw exception("Cannot branch while inside a delay slot");
|
throw exception("Cannot branch while inside a delay slot");
|
||||||
|
|
||||||
u32 value = registers[opcode->srcA];
|
u32 value{registers[opcode->srcA]};
|
||||||
bool branch = (opcode->branchCondition == Opcode::BranchCondition::Zero) ? (value == 0) : (value != 0);
|
bool branch{(opcode->branchCondition == Opcode::BranchCondition::Zero) ? (value == 0) : (value != 0)};
|
||||||
|
|
||||||
if (branch) {
|
if (branch) {
|
||||||
if (opcode->noDelay) {
|
if (opcode->noDelay) {
|
||||||
opcode += opcode->immediate;
|
opcode += opcode->immediate;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
Opcode *targetOpcode = opcode + opcode->immediate;
|
Opcode *targetOpcode{opcode + opcode->immediate};
|
||||||
|
|
||||||
// Step into delay slot
|
// Step into delay slot
|
||||||
opcode++;
|
opcode++;
|
||||||
@ -111,25 +111,25 @@ namespace skyline::gpu {
|
|||||||
FORCE_INLINE u32 MacroInterpreter::HandleAlu(Opcode::AluOperation operation, u32 srcA, u32 srcB) {
|
FORCE_INLINE u32 MacroInterpreter::HandleAlu(Opcode::AluOperation operation, u32 srcA, u32 srcB) {
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case Opcode::AluOperation::Add: {
|
case Opcode::AluOperation::Add: {
|
||||||
u64 result = static_cast<u64>(srcA) + srcB;
|
u64 result{static_cast<u64>(srcA) + srcB};
|
||||||
|
|
||||||
carryFlag = result >> 32;
|
carryFlag = result >> 32;
|
||||||
return static_cast<u32>(result);
|
return static_cast<u32>(result);
|
||||||
}
|
}
|
||||||
case Opcode::AluOperation::AddWithCarry: {
|
case Opcode::AluOperation::AddWithCarry: {
|
||||||
u64 result = static_cast<u64>(srcA) + srcB + carryFlag;
|
u64 result{static_cast<u64>(srcA) + srcB + carryFlag};
|
||||||
|
|
||||||
carryFlag = result >> 32;
|
carryFlag = result >> 32;
|
||||||
return static_cast<u32>(result);
|
return static_cast<u32>(result);
|
||||||
}
|
}
|
||||||
case Opcode::AluOperation::Subtract: {
|
case Opcode::AluOperation::Subtract: {
|
||||||
u64 result = static_cast<u64>(srcA) - srcB;
|
u64 result{static_cast<u64>(srcA) - srcB};
|
||||||
|
|
||||||
carryFlag = result & 0xFFFFFFFF;
|
carryFlag = result & 0xFFFFFFFF;
|
||||||
return static_cast<u32>(result);
|
return static_cast<u32>(result);
|
||||||
}
|
}
|
||||||
case Opcode::AluOperation::SubtractWithBorrow: {
|
case Opcode::AluOperation::SubtractWithBorrow: {
|
||||||
u64 result = static_cast<u64>(srcA) - srcB - !carryFlag;
|
u64 result{static_cast<u64>(srcA) - srcB - !carryFlag};
|
||||||
|
|
||||||
carryFlag = result & 0xFFFFFFFF;
|
carryFlag = result & 0xFFFFFFFF;
|
||||||
return static_cast<u32>(result);
|
return static_cast<u32>(result);
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
namespace skyline::gpu::vmm {
|
namespace skyline::gpu::vmm {
|
||||||
MemoryManager::MemoryManager(const DeviceState &state) : state(state) {
|
MemoryManager::MemoryManager(const DeviceState &state) : state(state) {
|
||||||
constexpr u64 GpuAddressSpaceSize = 1ul << 40; //!< The size of the GPU address space
|
constexpr u64 GpuAddressSpaceSize{1ul << 40}; //!< The size of the GPU address space
|
||||||
constexpr u64 GpuAddressSpaceBase = 0x100000; //!< The base of the GPU address space - must be non-zero
|
constexpr u64 GpuAddressSpaceBase{0x100000}; //!< The base of the GPU address space - must be non-zero
|
||||||
|
|
||||||
// Create the initial chunk that will be split to create new chunks
|
// Create the initial chunk that will be split to create new chunks
|
||||||
ChunkDescriptor baseChunk(GpuAddressSpaceBase, GpuAddressSpaceSize, 0, ChunkState::Unmapped);
|
ChunkDescriptor baseChunk(GpuAddressSpaceBase, GpuAddressSpaceSize, 0, ChunkState::Unmapped);
|
||||||
@ -15,9 +15,9 @@ namespace skyline::gpu::vmm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ChunkDescriptor> MemoryManager::FindChunk(u64 size, ChunkState state) {
|
std::optional<ChunkDescriptor> MemoryManager::FindChunk(u64 size, ChunkState state) {
|
||||||
auto chunk = std::find_if(chunkList.begin(), chunkList.end(), [size, state](const ChunkDescriptor &chunk) -> bool {
|
auto chunk{std::find_if(chunkList.begin(), chunkList.end(), [size, state](const ChunkDescriptor &chunk) -> bool {
|
||||||
return chunk.size > size && chunk.state == state;
|
return chunk.size > size && chunk.state == state;
|
||||||
});
|
})};
|
||||||
|
|
||||||
if (chunk != chunkList.end())
|
if (chunk != chunkList.end())
|
||||||
return *chunk;
|
return *chunk;
|
||||||
@ -26,12 +26,12 @@ namespace skyline::gpu::vmm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u64 MemoryManager::InsertChunk(const ChunkDescriptor &newChunk) {
|
u64 MemoryManager::InsertChunk(const ChunkDescriptor &newChunk) {
|
||||||
auto chunkEnd = chunkList.end();
|
auto chunkEnd{chunkList.end()};
|
||||||
for (auto chunk = chunkList.begin(); chunk != chunkEnd; chunk++) {
|
for (auto chunk{chunkList.begin()}; chunk != chunkEnd; chunk++) {
|
||||||
if (chunk->CanContain(newChunk)) {
|
if (chunk->CanContain(newChunk)) {
|
||||||
auto oldChunk = *chunk;
|
auto oldChunk{*chunk};
|
||||||
u64 newSize = newChunk.address - chunk->address;
|
u64 newSize{newChunk.address - chunk->address};
|
||||||
u64 extension = chunk->size - newSize - newChunk.size;
|
u64 extension{chunk->size - newSize - newChunk.size};
|
||||||
|
|
||||||
if (newSize == 0) {
|
if (newSize == 0) {
|
||||||
*chunk = newChunk;
|
*chunk = newChunk;
|
||||||
@ -49,7 +49,7 @@ namespace skyline::gpu::vmm {
|
|||||||
chunk->size = newChunk.address - chunk->address;
|
chunk->size = newChunk.address - chunk->address;
|
||||||
|
|
||||||
// Deletes all chunks that are within the chunk being inserted and split the final one
|
// Deletes all chunks that are within the chunk being inserted and split the final one
|
||||||
auto tailChunk = std::next(chunk);
|
auto tailChunk{std::next(chunk)};
|
||||||
while (tailChunk != chunkEnd) {
|
while (tailChunk != chunkEnd) {
|
||||||
if (tailChunk->address + tailChunk->size >= newChunk.address + newChunk.size)
|
if (tailChunk->address + tailChunk->size >= newChunk.address + newChunk.size)
|
||||||
break;
|
break;
|
||||||
@ -62,7 +62,7 @@ namespace skyline::gpu::vmm {
|
|||||||
if (tailChunk == chunkEnd)
|
if (tailChunk == chunkEnd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
u64 chunkSliceOffset = newChunk.address + newChunk.size - tailChunk->address;
|
u64 chunkSliceOffset{newChunk.address + newChunk.size - tailChunk->address};
|
||||||
tailChunk->address += chunkSliceOffset;
|
tailChunk->address += chunkSliceOffset;
|
||||||
tailChunk->size -= chunkSliceOffset;
|
tailChunk->size -= chunkSliceOffset;
|
||||||
if (tailChunk->state == ChunkState::Mapped)
|
if (tailChunk->state == ChunkState::Mapped)
|
||||||
@ -70,7 +70,7 @@ namespace skyline::gpu::vmm {
|
|||||||
|
|
||||||
|
|
||||||
// If the size of the head chunk is zero then we can directly replace it with our new one rather than inserting it
|
// If the size of the head chunk is zero then we can directly replace it with our new one rather than inserting it
|
||||||
auto headChunk = std::prev(tailChunk);
|
auto headChunk{std::prev(tailChunk)};
|
||||||
if (headChunk->size == 0)
|
if (headChunk->size == 0)
|
||||||
*headChunk = newChunk;
|
*headChunk = newChunk;
|
||||||
else
|
else
|
||||||
@ -85,11 +85,11 @@ namespace skyline::gpu::vmm {
|
|||||||
|
|
||||||
u64 MemoryManager::ReserveSpace(u64 size) {
|
u64 MemoryManager::ReserveSpace(u64 size) {
|
||||||
size = util::AlignUp(size, constant::GpuPageSize);
|
size = util::AlignUp(size, constant::GpuPageSize);
|
||||||
auto newChunk = FindChunk(size, ChunkState::Unmapped);
|
auto newChunk{FindChunk(size, ChunkState::Unmapped)};
|
||||||
if (!newChunk)
|
if (!newChunk)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto chunk = *newChunk;
|
auto chunk{*newChunk};
|
||||||
chunk.size = size;
|
chunk.size = size;
|
||||||
chunk.state = ChunkState::Reserved;
|
chunk.state = ChunkState::Reserved;
|
||||||
|
|
||||||
@ -107,11 +107,11 @@ namespace skyline::gpu::vmm {
|
|||||||
|
|
||||||
u64 MemoryManager::MapAllocate(u64 address, u64 size) {
|
u64 MemoryManager::MapAllocate(u64 address, u64 size) {
|
||||||
size = util::AlignUp(size, constant::GpuPageSize);
|
size = util::AlignUp(size, constant::GpuPageSize);
|
||||||
auto mappedChunk = FindChunk(size, ChunkState::Unmapped);
|
auto mappedChunk{FindChunk(size, ChunkState::Unmapped)};
|
||||||
if (!mappedChunk)
|
if (!mappedChunk)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto chunk = *mappedChunk;
|
auto chunk{*mappedChunk};
|
||||||
chunk.cpuAddress = address;
|
chunk.cpuAddress = address;
|
||||||
chunk.size = size;
|
chunk.size = size;
|
||||||
chunk.state = ChunkState::Mapped;
|
chunk.state = ChunkState::Mapped;
|
||||||
@ -132,9 +132,9 @@ namespace skyline::gpu::vmm {
|
|||||||
if (!util::IsAligned(address, constant::GpuPageSize))
|
if (!util::IsAligned(address, constant::GpuPageSize))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto chunk = std::find_if(chunkList.begin(), chunkList.end(), [address](const ChunkDescriptor &chunk) -> bool {
|
auto chunk{std::find_if(chunkList.begin(), chunkList.end(), [address](const ChunkDescriptor &chunk) -> bool {
|
||||||
return chunk.address == address;
|
return chunk.address == address;
|
||||||
});
|
})};
|
||||||
|
|
||||||
if (chunk == chunkList.end())
|
if (chunk == chunkList.end())
|
||||||
return false;
|
return false;
|
||||||
@ -146,9 +146,9 @@ namespace skyline::gpu::vmm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::Read(u8 *destination, u64 address, u64 size) const {
|
void MemoryManager::Read(u8 *destination, u64 address, u64 size) const {
|
||||||
auto chunk = std::upper_bound(chunkList.begin(), chunkList.end(), address, [](const u64 address, const ChunkDescriptor &chunk) -> bool {
|
auto chunk{std::upper_bound(chunkList.begin(), chunkList.end(), address, [](const u64 address, const ChunkDescriptor &chunk) -> bool {
|
||||||
return address < chunk.address;
|
return address < chunk.address;
|
||||||
});
|
})};
|
||||||
|
|
||||||
if (chunk == chunkList.end() || chunk->state != ChunkState::Mapped)
|
if (chunk == chunkList.end() || chunk->state != ChunkState::Mapped)
|
||||||
throw exception("Failed to read region in GPU address space: Address: 0x{:X}, Size: 0x{:X}", address, size);
|
throw exception("Failed to read region in GPU address space: Address: 0x{:X}, Size: 0x{:X}", address, size);
|
||||||
@ -176,9 +176,9 @@ namespace skyline::gpu::vmm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::Write(u8 *source, u64 address, u64 size) const {
|
void MemoryManager::Write(u8 *source, u64 address, u64 size) const {
|
||||||
auto chunk = std::upper_bound(chunkList.begin(), chunkList.end(), address, [](const u64 address, const ChunkDescriptor &chunk) -> bool {
|
auto chunk{std::upper_bound(chunkList.begin(), chunkList.end(), address, [](const u64 address, const ChunkDescriptor &chunk) -> bool {
|
||||||
return address < chunk.address;
|
return address < chunk.address;
|
||||||
});
|
})};
|
||||||
|
|
||||||
if (chunk == chunkList.end() || chunk->state != ChunkState::Mapped)
|
if (chunk == chunkList.end() || chunk->state != ChunkState::Mapped)
|
||||||
throw exception("Failed to write region in GPU address space: Address: 0x{:X}, Size: 0x{:X}", address, size);
|
throw exception("Failed to write region in GPU address space: Address: 0x{:X}, Size: 0x{:X}", address, size);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr u64 GpuPageSize = 1 << 16; //!< The page size of the GPU address space
|
constexpr u64 GpuPageSize{1 << 16}; //!< The page size of the GPU address space
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace gpu::vmm {
|
namespace gpu::vmm {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr size_t MaxHwSyncpointCount = 192; //!< The maximum number of HOST1X syncpoints on t210
|
constexpr size_t MaxHwSyncpointCount{192}; //!< The maximum number of HOST1X syncpoints on t210
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
@ -14,38 +14,38 @@ namespace skyline::gpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Texture::SynchronizeHost() {
|
void Texture::SynchronizeHost() {
|
||||||
auto texture = state.process->GetPointer<u8>(guest->address);
|
auto texture{state.process->GetPointer<u8>(guest->address)};
|
||||||
auto size = format.GetSize(dimensions);
|
auto size{format.GetSize(dimensions)};
|
||||||
backing.resize(size);
|
backing.resize(size);
|
||||||
auto output = reinterpret_cast<u8 *>(backing.data());
|
auto output{reinterpret_cast<u8 *>(backing.data())};
|
||||||
|
|
||||||
if (guest->tileMode == texture::TileMode::Block) {
|
if (guest->tileMode == texture::TileMode::Block) {
|
||||||
// Reference on Block-linear tiling: https://gist.github.com/PixelyIon/d9c35050af0ef5690566ca9f0965bc32
|
// Reference on Block-linear tiling: https://gist.github.com/PixelyIon/d9c35050af0ef5690566ca9f0965bc32
|
||||||
constexpr u8 sectorWidth = 16; // The width of a sector in bytes
|
constexpr u8 sectorWidth{16}; // The width of a sector in bytes
|
||||||
constexpr u8 sectorHeight = 2; // The height of a sector in lines
|
constexpr u8 sectorHeight{2}; // The height of a sector in lines
|
||||||
constexpr u8 gobWidth = 64; // The width of a GOB in bytes
|
constexpr u8 gobWidth{64}; // The width of a GOB in bytes
|
||||||
constexpr u8 gobHeight = 8; // The height of a GOB in lines
|
constexpr u8 gobHeight{8}; // The height of a GOB in lines
|
||||||
|
|
||||||
auto blockHeight = guest->tileConfig.blockHeight; // The height of the blocks in GOBs
|
auto blockHeight{guest->tileConfig.blockHeight}; // The height of the blocks in GOBs
|
||||||
auto robHeight = gobHeight * blockHeight; // The height of a single ROB (Row of Blocks) in lines
|
auto robHeight{gobHeight * blockHeight}; // The height of a single ROB (Row of Blocks) in lines
|
||||||
auto surfaceHeight = dimensions.height / format.blockHeight; // The height of the surface in lines
|
auto surfaceHeight{dimensions.height / format.blockHeight}; // The height of the surface in lines
|
||||||
auto surfaceHeightRobs = util::AlignUp(surfaceHeight, robHeight) / robHeight; // The height of the surface in ROBs (Row Of Blocks)
|
auto surfaceHeightRobs{util::AlignUp(surfaceHeight, robHeight) / robHeight}; // The height of the surface in ROBs (Row Of Blocks)
|
||||||
auto robWidthBytes = util::AlignUp((guest->tileConfig.surfaceWidth / format.blockWidth) * format.bpb, gobWidth); // The width of a ROB in bytes
|
auto robWidthBytes{util::AlignUp((guest->tileConfig.surfaceWidth / format.blockWidth) * format.bpb, gobWidth)}; // The width of a ROB in bytes
|
||||||
auto robWidthBlocks = robWidthBytes / gobWidth; // The width of a ROB in blocks (and GOBs because block width == 1 on the Tegra X1)
|
auto robWidthBlocks{robWidthBytes / gobWidth}; // The width of a ROB in blocks (and GOBs because block width == 1 on the Tegra X1)
|
||||||
auto robBytes = robWidthBytes * robHeight; // The size of a ROB in bytes
|
auto robBytes{robWidthBytes * robHeight}; // The size of a ROB in bytes
|
||||||
auto gobYOffset = robWidthBytes * gobHeight; // The offset of the next Y-axis GOB from the current one in linear space
|
auto gobYOffset{robWidthBytes * gobHeight}; // The offset of the next Y-axis GOB from the current one in linear space
|
||||||
|
|
||||||
auto inputSector = texture; // The address of the input sector
|
auto inputSector{texture}; // The address of the input sector
|
||||||
auto outputRob = output; // The address of the output block
|
auto outputRob{output}; // The address of the output block
|
||||||
|
|
||||||
for (u32 rob = 0, y = 0, paddingY = 0; rob < surfaceHeightRobs; rob++) { // Every Surface contains `surfaceHeightRobs` ROBs
|
for (u32 rob{}, y{}, paddingY{}; rob < surfaceHeightRobs; rob++) { // Every Surface contains `surfaceHeightRobs` ROBs
|
||||||
auto outputBlock = outputRob; // We iterate through a block independently of the ROB
|
auto outputBlock{outputRob}; // We iterate through a block independently of the ROB
|
||||||
for (u32 block = 0; block < robWidthBlocks; block++) { // Every ROB contains `surfaceWidthBlocks` Blocks
|
for (u32 block{}; block < robWidthBlocks; block++) { // Every ROB contains `surfaceWidthBlocks` Blocks
|
||||||
auto outputGob = outputBlock; // We iterate through a GOB independently of the block
|
auto outputGob{outputBlock}; // We iterate through a GOB independently of the block
|
||||||
for (u32 gobY = 0; gobY < blockHeight; gobY++) { // Every Block contains `blockHeight` Y-axis GOBs
|
for (u32 gobY{}; gobY < blockHeight; gobY++) { // Every Block contains `blockHeight` Y-axis GOBs
|
||||||
for (u32 index = 0; index < sectorWidth * sectorHeight; index++) { // Every Y-axis GOB contains `sectorWidth * sectorHeight` sectors
|
for (u32 index{}; index < sectorWidth * sectorHeight; index++) { // Every Y-axis GOB contains `sectorWidth * sectorHeight` sectors
|
||||||
u32 xT = ((index << 3) & 0b10000) | ((index << 1) & 0b100000); // Morton-Swizzle on the X-axis
|
u32 xT{((index << 3) & 0b10000) | ((index << 1) & 0b100000)}; // Morton-Swizzle on the X-axis
|
||||||
u32 yT = ((index >> 1) & 0b110) | (index & 0b1); // Morton-Swizzle on the Y-axis
|
u32 yT{((index >> 1) & 0b110) | (index & 0b1)}; // Morton-Swizzle on the Y-axis
|
||||||
std::memcpy(outputGob + (yT * robWidthBytes) + xT, inputSector, sectorWidth);
|
std::memcpy(outputGob + (yT * robWidthBytes) + xT, inputSector, sectorWidth);
|
||||||
inputSector += sectorWidth; // `sectorWidth` bytes are of sequential image data
|
inputSector += sectorWidth; // `sectorWidth` bytes are of sequential image data
|
||||||
}
|
}
|
||||||
@ -61,13 +61,13 @@ namespace skyline::gpu {
|
|||||||
paddingY = (guest->tileConfig.blockHeight - blockHeight) * (sectorWidth * sectorWidth * sectorHeight); // Calculate the amount of padding between contiguous sectors
|
paddingY = (guest->tileConfig.blockHeight - blockHeight) * (sectorWidth * sectorWidth * sectorHeight); // Calculate the amount of padding between contiguous sectors
|
||||||
}
|
}
|
||||||
} else if (guest->tileMode == texture::TileMode::Pitch) {
|
} else if (guest->tileMode == texture::TileMode::Pitch) {
|
||||||
auto sizeLine = guest->format.GetSize(dimensions.width, 1); // The size of a single line of pixel data
|
auto sizeLine{guest->format.GetSize(dimensions.width, 1)}; // The size of a single line of pixel data
|
||||||
auto sizeStride = guest->format.GetSize(guest->tileConfig.pitch, 1); // The size of a single stride of pixel data
|
auto sizeStride{guest->format.GetSize(guest->tileConfig.pitch, 1)}; // The size of a single stride of pixel data
|
||||||
|
|
||||||
auto inputLine = texture; // The address of the input line
|
auto inputLine{texture}; // The address of the input line
|
||||||
auto outputLine = output; // The address of the output line
|
auto outputLine{output}; // The address of the output line
|
||||||
|
|
||||||
for (u32 line = 0; line < dimensions.height; line++) {
|
for (u32 line{}; line < dimensions.height; line++) {
|
||||||
std::memcpy(outputLine, inputLine, sizeLine);
|
std::memcpy(outputLine, inputLine, sizeLine);
|
||||||
inputLine += sizeStride;
|
inputLine += sizeStride;
|
||||||
outputLine += sizeLine;
|
outputLine += sizeLine;
|
||||||
|
@ -184,7 +184,7 @@ namespace skyline {
|
|||||||
std::shared_ptr<PresentationTexture> InitializePresentationTexture() {
|
std::shared_ptr<PresentationTexture> InitializePresentationTexture() {
|
||||||
if (host)
|
if (host)
|
||||||
throw exception("Trying to create multiple PresentationTexture objects from a single GuestTexture");
|
throw exception("Trying to create multiple PresentationTexture objects from a single GuestTexture");
|
||||||
auto presentation = std::make_shared<PresentationTexture>(state, shared_from_this(), dimensions, format);
|
auto presentation{std::make_shared<PresentationTexture>(state, shared_from_this(), dimensions, format)};
|
||||||
host = std::static_pointer_cast<Texture>(presentation);
|
host = std::static_pointer_cast<Texture>(presentation);
|
||||||
return presentation;
|
return presentation;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ namespace skyline::input {
|
|||||||
if (id == NpadId::Unknown)
|
if (id == NpadId::Unknown)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto &device = at(id);
|
auto &device{at(id)};
|
||||||
|
|
||||||
for (auto &controller : controllers) {
|
for (auto &controller : controllers) {
|
||||||
if (controller.device)
|
if (controller.device)
|
||||||
|
@ -183,13 +183,13 @@ namespace skyline::input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NpadControllerState &NpadDevice::GetNextEntry(NpadControllerInfo &info) {
|
NpadControllerState &NpadDevice::GetNextEntry(NpadControllerInfo &info) {
|
||||||
auto &lastEntry = info.state.at(info.header.currentEntry);
|
auto &lastEntry{info.state.at(info.header.currentEntry)};
|
||||||
|
|
||||||
info.header.timestamp = util::GetTimeTicks();
|
info.header.timestamp = util::GetTimeTicks();
|
||||||
info.header.entryCount = std::min(static_cast<u8>(info.header.entryCount + 1), constant::HidEntryCount);
|
info.header.entryCount = std::min(static_cast<u8>(info.header.entryCount + 1), constant::HidEntryCount);
|
||||||
info.header.currentEntry = (info.header.currentEntry != constant::HidEntryCount - 1) ? info.header.currentEntry + 1 : 0;
|
info.header.currentEntry = (info.header.currentEntry != constant::HidEntryCount - 1) ? info.header.currentEntry + 1 : 0;
|
||||||
|
|
||||||
auto &entry = info.state.at(info.header.currentEntry);
|
auto &entry{info.state.at(info.header.currentEntry)};
|
||||||
|
|
||||||
entry.globalTimestamp = globalTimestamp;
|
entry.globalTimestamp = globalTimestamp;
|
||||||
entry.localTimestamp = lastEntry.localTimestamp + 1;
|
entry.localTimestamp = lastEntry.localTimestamp + 1;
|
||||||
@ -207,7 +207,7 @@ namespace skyline::input {
|
|||||||
if (!connectionState.connected)
|
if (!connectionState.connected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto &entry = GetNextEntry(*controllerInfo);
|
auto &entry{GetNextEntry(*controllerInfo)};
|
||||||
|
|
||||||
if (pressed)
|
if (pressed)
|
||||||
entry.buttons.raw |= mask.raw;
|
entry.buttons.raw |= mask.raw;
|
||||||
@ -247,7 +247,7 @@ namespace skyline::input {
|
|||||||
mask = orientedMask;
|
mask = orientedMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &defaultEntry = GetNextEntry(section.defaultController);
|
auto &defaultEntry{GetNextEntry(section.defaultController)};
|
||||||
if (pressed)
|
if (pressed)
|
||||||
defaultEntry.buttons.raw |= mask.raw;
|
defaultEntry.buttons.raw |= mask.raw;
|
||||||
else
|
else
|
||||||
@ -260,10 +260,10 @@ namespace skyline::input {
|
|||||||
if (!connectionState.connected)
|
if (!connectionState.connected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto &controllerEntry = GetNextEntry(*controllerInfo);
|
auto &controllerEntry{GetNextEntry(*controllerInfo)};
|
||||||
auto &defaultEntry = GetNextEntry(section.defaultController);
|
auto &defaultEntry{GetNextEntry(section.defaultController)};
|
||||||
|
|
||||||
constexpr i16 threshold = std::numeric_limits<i16>::max() / 2; // A 50% deadzone for the stick buttons
|
constexpr i16 threshold{std::numeric_limits<i16>::max() / 2}; // A 50% deadzone for the stick buttons
|
||||||
|
|
||||||
if (manager.orientation == NpadJoyOrientation::Vertical || (type != NpadControllerType::JoyconLeft && type != NpadControllerType::JoyconRight)) {
|
if (manager.orientation == NpadJoyOrientation::Vertical || (type != NpadControllerType::JoyconLeft && type != NpadControllerType::JoyconRight)) {
|
||||||
switch (axis) {
|
switch (axis) {
|
||||||
@ -389,7 +389,7 @@ namespace skyline::input {
|
|||||||
|
|
||||||
u8 startCycleCount{};
|
u8 startCycleCount{};
|
||||||
for (u8 n{}; n < vibrations.size(); n++) {
|
for (u8 n{}; n < vibrations.size(); n++) {
|
||||||
auto &vibration = vibrations[n];
|
auto &vibration{vibrations[n]};
|
||||||
if (totalTime <= vibration.start) {
|
if (totalTime <= vibration.start) {
|
||||||
vibration.start = vibration.end + vibration.period;
|
vibration.start = vibration.end + vibration.period;
|
||||||
totalAmplitude += vibration.amplitude;
|
totalAmplitude += vibration.amplitude;
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
#include "shared_mem.h"
|
#include "shared_mem.h"
|
||||||
|
|
||||||
namespace skyline::constant {
|
namespace skyline::constant {
|
||||||
constexpr jlong MsInSecond = 1000; //!< The amount of milliseconds in a single second of time
|
constexpr jlong MsInSecond{1000}; //!< The amount of milliseconds in a single second of time
|
||||||
constexpr jint AmplitudeMax = std::numeric_limits<u8>::max(); //!< The maximum amplitude for Android Vibration APIs
|
constexpr jint AmplitudeMax{std::numeric_limits<u8>::max()}; //!< The maximum amplitude for Android Vibration APIs
|
||||||
constexpr i8 NullIndex = -1; //!< The placeholder index value when there is no device present
|
constexpr i8 NullIndex{-1}; //!< The placeholder index value when there is no device present
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace skyline::input {
|
namespace skyline::input {
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr u8 HidEntryCount = 17; //!< The amount of entries in each HID device
|
constexpr u8 HidEntryCount{17}; //!< The amount of entries in each HID device
|
||||||
constexpr u8 NpadCount = 10; //!< The amount of NPads in shared memory
|
constexpr u8 NpadCount{10}; //!< The amount of NPads in shared memory
|
||||||
constexpr u8 ControllerCount = 8; //!< The maximum amount of guest controllers
|
constexpr u8 ControllerCount{8}; //!< The maximum amount of guest controllers
|
||||||
constexpr u32 NpadBatteryFull = 2; //!< The full battery state of an npad
|
constexpr u32 NpadBatteryFull{2}; //!< The full battery state of an npad
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace input {
|
namespace input {
|
||||||
|
@ -17,16 +17,16 @@ namespace skyline::input {
|
|||||||
if (!activated)
|
if (!activated)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto& lastEntry = section.entries[section.header.currentEntry];
|
const auto& lastEntry{section.entries[section.header.currentEntry]};
|
||||||
auto entryIndex = (section.header.currentEntry != constant::HidEntryCount - 1) ? section.header.currentEntry + 1 : 0;
|
auto entryIndex{(section.header.currentEntry != constant::HidEntryCount - 1) ? section.header.currentEntry + 1 : 0};
|
||||||
auto& entry = section.entries[entryIndex];
|
auto& entry{section.entries[entryIndex]};
|
||||||
entry.globalTimestamp = lastEntry.globalTimestamp + 1;
|
entry.globalTimestamp = lastEntry.globalTimestamp + 1;
|
||||||
entry.localTimestamp = lastEntry.localTimestamp + 1;
|
entry.localTimestamp = lastEntry.localTimestamp + 1;
|
||||||
entry.touchCount = points.size();
|
entry.touchCount = points.size();
|
||||||
|
|
||||||
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 = i;
|
||||||
guest.positionX = host.x;
|
guest.positionX = host.x;
|
||||||
guest.positionY = host.y;
|
guest.positionY = host.y;
|
||||||
|
@ -48,9 +48,9 @@ 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(timings.size())};
|
||||||
env->SetLongArrayRegion(jTimings, 0, timings.size(), timings.data());
|
env->SetLongArrayRegion(jTimings, 0, timings.size(), timings.data());
|
||||||
auto jAmplitudes = env->NewIntArray(amplitudes.size());
|
auto jAmplitudes{env->NewIntArray(amplitudes.size())};
|
||||||
env->SetIntArrayRegion(jAmplitudes, 0, amplitudes.size(), amplitudes.data());
|
env->SetIntArrayRegion(jAmplitudes, 0, amplitudes.size(), amplitudes.data());
|
||||||
|
|
||||||
env->CallVoidMethod(instance, vibrateDeviceId, index, jTimings, jAmplitudes);
|
env->CallVoidMethod(instance, vibrateDeviceId, index, jTimings, jAmplitudes);
|
||||||
|
@ -47,7 +47,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
template<typename objectType>
|
template<typename objectType>
|
||||||
inline objectType GetField(const char *key) {
|
inline objectType GetField(const char *key) {
|
||||||
JNIEnv *env = GetEnv();
|
JNIEnv *env{GetEnv()};
|
||||||
if constexpr(std::is_same<objectType, jboolean>())
|
if constexpr(std::is_same<objectType, jboolean>())
|
||||||
return env->GetBooleanField(instance, env->GetFieldID(instanceClass, key, "Z"));
|
return env->GetBooleanField(instance, env->GetFieldID(instanceClass, key, "Z"));
|
||||||
else if constexpr(std::is_same<objectType, jbyte>())
|
else if constexpr(std::is_same<objectType, jbyte>())
|
||||||
|
@ -6,29 +6,29 @@
|
|||||||
|
|
||||||
namespace skyline::kernel::ipc {
|
namespace skyline::kernel::ipc {
|
||||||
IpcRequest::IpcRequest(bool isDomain, const DeviceState &state) : isDomain(isDomain) {
|
IpcRequest::IpcRequest(bool isDomain, const DeviceState &state) : isDomain(isDomain) {
|
||||||
u8 *tls = state.process->GetPointer<u8>(state.thread->tls);
|
u8 *tls{state.process->GetPointer<u8>(state.thread->tls)};
|
||||||
u8 *pointer = tls;
|
u8 *pointer{tls};
|
||||||
|
|
||||||
header = reinterpret_cast<CommandHeader *>(pointer);
|
header = reinterpret_cast<CommandHeader *>(pointer);
|
||||||
pointer += sizeof(CommandHeader);
|
pointer += sizeof(CommandHeader);
|
||||||
|
|
||||||
size_t cBufferLengthSize = util::AlignUp(((header->cFlag == BufferCFlag::None) ? 0 : ((header->cFlag > BufferCFlag::SingleDescriptor) ? (static_cast<u8>(header->cFlag) - 2) : 1)) * sizeof(u16), sizeof(u32));
|
size_t cBufferLengthSize{util::AlignUp(((header->cFlag == BufferCFlag::None) ? 0 : ((header->cFlag > BufferCFlag::SingleDescriptor) ? (static_cast<u8>(header->cFlag) - 2) : 1)) * sizeof(u16), sizeof(u32))};
|
||||||
|
|
||||||
if (header->handleDesc) {
|
if (header->handleDesc) {
|
||||||
handleDesc = reinterpret_cast<HandleDescriptor *>(pointer);
|
handleDesc = reinterpret_cast<HandleDescriptor *>(pointer);
|
||||||
pointer += sizeof(HandleDescriptor) + (handleDesc->sendPid ? sizeof(u64) : 0);
|
pointer += sizeof(HandleDescriptor) + (handleDesc->sendPid ? sizeof(u64) : 0);
|
||||||
for (u32 index = 0; handleDesc->copyCount > index; index++) {
|
for (u32 index{}; handleDesc->copyCount > index; index++) {
|
||||||
copyHandles.push_back(*reinterpret_cast<KHandle *>(pointer));
|
copyHandles.push_back(*reinterpret_cast<KHandle *>(pointer));
|
||||||
pointer += sizeof(KHandle);
|
pointer += sizeof(KHandle);
|
||||||
}
|
}
|
||||||
for (u32 index = 0; handleDesc->moveCount > index; index++) {
|
for (u32 index{}; handleDesc->moveCount > index; index++) {
|
||||||
moveHandles.push_back(*reinterpret_cast<KHandle *>(pointer));
|
moveHandles.push_back(*reinterpret_cast<KHandle *>(pointer));
|
||||||
pointer += sizeof(KHandle);
|
pointer += sizeof(KHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u8 index = 0; header->xNo > index; index++) {
|
for (u8 index{}; header->xNo > index; index++) {
|
||||||
auto bufX = reinterpret_cast<BufferDescriptorX *>(pointer);
|
auto bufX{reinterpret_cast<BufferDescriptorX *>(pointer)};
|
||||||
if (bufX->Address()) {
|
if (bufX->Address()) {
|
||||||
inputBuf.emplace_back(state.process->GetPointer<u8>(bufX->Address()), u16(bufX->size));
|
inputBuf.emplace_back(state.process->GetPointer<u8>(bufX->Address()), u16(bufX->size));
|
||||||
state.logger->Debug("Buf X #{} AD: 0x{:X} SZ: 0x{:X} CTR: {}", index, u64(bufX->Address()), u16(bufX->size), u16(bufX->Counter()));
|
state.logger->Debug("Buf X #{} AD: 0x{:X} SZ: 0x{:X} CTR: {}", index, u64(bufX->Address()), u16(bufX->size), u16(bufX->Counter()));
|
||||||
@ -36,8 +36,8 @@ namespace skyline::kernel::ipc {
|
|||||||
pointer += sizeof(BufferDescriptorX);
|
pointer += sizeof(BufferDescriptorX);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u8 index = 0; header->aNo > index; index++) {
|
for (u8 index{}; header->aNo > index; index++) {
|
||||||
auto bufA = reinterpret_cast<BufferDescriptorABW *>(pointer);
|
auto bufA{reinterpret_cast<BufferDescriptorABW *>(pointer)};
|
||||||
if (bufA->Address()) {
|
if (bufA->Address()) {
|
||||||
inputBuf.emplace_back(state.process->GetPointer<u8>(bufA->Address()), bufA->Size());
|
inputBuf.emplace_back(state.process->GetPointer<u8>(bufA->Address()), bufA->Size());
|
||||||
state.logger->Debug("Buf A #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufA->Address()), u64(bufA->Size()));
|
state.logger->Debug("Buf A #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufA->Address()), u64(bufA->Size()));
|
||||||
@ -45,8 +45,8 @@ namespace skyline::kernel::ipc {
|
|||||||
pointer += sizeof(BufferDescriptorABW);
|
pointer += sizeof(BufferDescriptorABW);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u8 index = 0; header->bNo > index; index++) {
|
for (u8 index{}; header->bNo > index; index++) {
|
||||||
auto bufB = reinterpret_cast<BufferDescriptorABW *>(pointer);
|
auto bufB{reinterpret_cast<BufferDescriptorABW *>(pointer)};
|
||||||
if (bufB->Address()) {
|
if (bufB->Address()) {
|
||||||
outputBuf.emplace_back(state.process->GetPointer<u8>(bufB->Address()), bufB->Size());
|
outputBuf.emplace_back(state.process->GetPointer<u8>(bufB->Address()), bufB->Size());
|
||||||
state.logger->Debug("Buf B #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufB->Address()), u64(bufB->Size()));
|
state.logger->Debug("Buf B #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufB->Address()), u64(bufB->Size()));
|
||||||
@ -54,8 +54,8 @@ namespace skyline::kernel::ipc {
|
|||||||
pointer += sizeof(BufferDescriptorABW);
|
pointer += sizeof(BufferDescriptorABW);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u8 index = 0; header->wNo > index; index++) {
|
for (u8 index{}; header->wNo > index; index++) {
|
||||||
auto bufW = reinterpret_cast<BufferDescriptorABW *>(pointer);
|
auto bufW{reinterpret_cast<BufferDescriptorABW *>(pointer)};
|
||||||
if (bufW->Address()) {
|
if (bufW->Address()) {
|
||||||
outputBuf.emplace_back(state.process->GetPointer<u8>(bufW->Address()), bufW->Size());
|
outputBuf.emplace_back(state.process->GetPointer<u8>(bufW->Address()), bufW->Size());
|
||||||
outputBuf.emplace_back(state.process->GetPointer<u8>(bufW->Address()), bufW->Size());
|
outputBuf.emplace_back(state.process->GetPointer<u8>(bufW->Address()), bufW->Size());
|
||||||
@ -64,8 +64,8 @@ namespace skyline::kernel::ipc {
|
|||||||
pointer += sizeof(BufferDescriptorABW);
|
pointer += sizeof(BufferDescriptorABW);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto offset = reinterpret_cast<u64>(pointer) - reinterpret_cast<u64>(tls); // We calculate the relative offset as the absolute one might differ
|
auto offset{reinterpret_cast<u64>(pointer) - reinterpret_cast<u64>(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;
|
||||||
|
|
||||||
if (isDomain && (header->type == CommandType::Request || header->type == CommandType::RequestWithContext)) {
|
if (isDomain && (header->type == CommandType::Request || header->type == CommandType::RequestWithContext)) {
|
||||||
@ -79,7 +79,7 @@ namespace skyline::kernel::ipc {
|
|||||||
cmdArgSz = domain->payloadSz - sizeof(PayloadHeader);
|
cmdArgSz = domain->payloadSz - sizeof(PayloadHeader);
|
||||||
pointer += cmdArgSz;
|
pointer += cmdArgSz;
|
||||||
|
|
||||||
for (u8 index = 0; domain->inputCount > index; index++) {
|
for (u8 index{}; domain->inputCount > index; index++) {
|
||||||
domainObjects.push_back(*reinterpret_cast<KHandle *>(pointer));
|
domainObjects.push_back(*reinterpret_cast<KHandle *>(pointer));
|
||||||
pointer += sizeof(KHandle);
|
pointer += sizeof(KHandle);
|
||||||
}
|
}
|
||||||
@ -100,14 +100,14 @@ namespace skyline::kernel::ipc {
|
|||||||
pointer += constant::IpcPaddingSum - padding + cBufferLengthSize;
|
pointer += constant::IpcPaddingSum - padding + cBufferLengthSize;
|
||||||
|
|
||||||
if (header->cFlag == BufferCFlag::SingleDescriptor) {
|
if (header->cFlag == BufferCFlag::SingleDescriptor) {
|
||||||
auto bufC = reinterpret_cast<BufferDescriptorC *>(pointer);
|
auto bufC{reinterpret_cast<BufferDescriptorC *>(pointer)};
|
||||||
if (bufC->address) {
|
if (bufC->address) {
|
||||||
outputBuf.emplace_back(state.process->GetPointer<u8>(bufC->address), u16(bufC->size));
|
outputBuf.emplace_back(state.process->GetPointer<u8>(bufC->address), u16(bufC->size));
|
||||||
state.logger->Debug("Buf C: AD: 0x{:X} SZ: 0x{:X}", u64(bufC->address), u16(bufC->size));
|
state.logger->Debug("Buf C: AD: 0x{:X} SZ: 0x{:X}", u64(bufC->address), u16(bufC->size));
|
||||||
}
|
}
|
||||||
} else if (header->cFlag > BufferCFlag::SingleDescriptor) {
|
} else if (header->cFlag > BufferCFlag::SingleDescriptor) {
|
||||||
for (u8 index = 0; (static_cast<u8>(header->cFlag) - 2) > index; index++) { // (cFlag - 2) C descriptors are present
|
for (u8 index{}; (static_cast<u8>(header->cFlag) - 2) > index; index++) { // (cFlag - 2) C descriptors are present
|
||||||
auto bufC = reinterpret_cast<BufferDescriptorC *>(pointer);
|
auto bufC{reinterpret_cast<BufferDescriptorC *>(pointer)};
|
||||||
if (bufC->address) {
|
if (bufC->address) {
|
||||||
outputBuf.emplace_back(state.process->GetPointer<u8>(bufC->address), u16(bufC->size));
|
outputBuf.emplace_back(state.process->GetPointer<u8>(bufC->address), u16(bufC->size));
|
||||||
state.logger->Debug("Buf C #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufC->address), u16(bufC->size));
|
state.logger->Debug("Buf C #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufC->address), u16(bufC->size));
|
||||||
@ -129,18 +129,18 @@ namespace skyline::kernel::ipc {
|
|||||||
IpcResponse::IpcResponse(const DeviceState &state) : state(state) {}
|
IpcResponse::IpcResponse(const DeviceState &state) : state(state) {}
|
||||||
|
|
||||||
void IpcResponse::WriteResponse(bool isDomain) {
|
void IpcResponse::WriteResponse(bool isDomain) {
|
||||||
auto tls = state.process->GetPointer<u8>(state.thread->tls);
|
auto tls{state.process->GetPointer<u8>(state.thread->tls)};
|
||||||
u8 *pointer = tls;
|
u8 *pointer{tls};
|
||||||
|
|
||||||
memset(tls, 0, constant::TlsIpcSize);
|
memset(tls, 0, constant::TlsIpcSize);
|
||||||
|
|
||||||
auto header = reinterpret_cast<CommandHeader *>(pointer);
|
auto header{reinterpret_cast<CommandHeader *>(pointer)};
|
||||||
header->rawSize = static_cast<u32>((sizeof(PayloadHeader) + payload.size() + (domainObjects.size() * sizeof(KHandle)) + constant::IpcPaddingSum + (isDomain ? sizeof(DomainHeaderRequest) : 0)) / sizeof(u32)); // Size is in 32-bit units because Nintendo
|
header->rawSize = static_cast<u32>((sizeof(PayloadHeader) + payload.size() + (domainObjects.size() * sizeof(KHandle)) + constant::IpcPaddingSum + (isDomain ? sizeof(DomainHeaderRequest) : 0)) / sizeof(u32)); // Size is in 32-bit units because Nintendo
|
||||||
header->handleDesc = (!copyHandles.empty() || !moveHandles.empty());
|
header->handleDesc = (!copyHandles.empty() || !moveHandles.empty());
|
||||||
pointer += sizeof(CommandHeader);
|
pointer += sizeof(CommandHeader);
|
||||||
|
|
||||||
if (header->handleDesc) {
|
if (header->handleDesc) {
|
||||||
auto handleDesc = reinterpret_cast<HandleDescriptor *>(pointer);
|
auto handleDesc{reinterpret_cast<HandleDescriptor *>(pointer)};
|
||||||
handleDesc->copyCount = static_cast<u8>(copyHandles.size());
|
handleDesc->copyCount = static_cast<u8>(copyHandles.size());
|
||||||
handleDesc->moveCount = static_cast<u8>(moveHandles.size());
|
handleDesc->moveCount = static_cast<u8>(moveHandles.size());
|
||||||
pointer += sizeof(HandleDescriptor);
|
pointer += sizeof(HandleDescriptor);
|
||||||
@ -156,17 +156,17 @@ namespace skyline::kernel::ipc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto offset = reinterpret_cast<u64>(pointer) - reinterpret_cast<u64>(tls); // We calculate the relative offset as the absolute one might differ
|
auto offset{reinterpret_cast<u64>(pointer) - reinterpret_cast<u64>(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;
|
||||||
|
|
||||||
if (isDomain) {
|
if (isDomain) {
|
||||||
auto domain = reinterpret_cast<DomainHeaderResponse *>(pointer);
|
auto domain{reinterpret_cast<DomainHeaderResponse *>(pointer)};
|
||||||
domain->outputCount = static_cast<u32>(domainObjects.size());
|
domain->outputCount = static_cast<u32>(domainObjects.size());
|
||||||
pointer += sizeof(DomainHeaderResponse);
|
pointer += sizeof(DomainHeaderResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto payloadHeader = reinterpret_cast<PayloadHeader *>(pointer);
|
auto payloadHeader{reinterpret_cast<PayloadHeader *>(pointer)};
|
||||||
payloadHeader->magic = util::MakeMagic<u32>("SFCO"); // SFCO is the magic in IPC responses
|
payloadHeader->magic = util::MakeMagic<u32>("SFCO"); // SFCO is the magic in IPC responses
|
||||||
payloadHeader->version = 1;
|
payloadHeader->version = 1;
|
||||||
payloadHeader->value = errorCode;
|
payloadHeader->value = errorCode;
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr auto IpcPaddingSum = 0x10; // The sum of the padding surrounding the data payload
|
constexpr u8 IpcPaddingSum{0x10}; // The sum of the padding surrounding the data payload
|
||||||
constexpr auto TlsIpcSize = 0x100; // The size of the IPC command buffer in a TLS slot
|
constexpr u16 TlsIpcSize{0x100}; // The size of the IPC command buffer in a TLS slot
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace kernel::ipc {
|
namespace kernel::ipc {
|
||||||
@ -228,7 +228,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
inline ValueType &Pop() {
|
inline ValueType &Pop() {
|
||||||
ValueType &value = *reinterpret_cast<ValueType *>(payloadOffset);
|
ValueType &value{*reinterpret_cast<ValueType *>(payloadOffset)};
|
||||||
payloadOffset += sizeof(ValueType);
|
payloadOffset += sizeof(ValueType);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ namespace skyline {
|
|||||||
* @param size The length of the string (0 means the string is null terminated)
|
* @param size The length of the string (0 means the string is null terminated)
|
||||||
*/
|
*/
|
||||||
inline std::string_view PopString(size_t size = 0) {
|
inline std::string_view PopString(size_t size = 0) {
|
||||||
auto view = size ? std::string_view(reinterpret_cast<const char *>(payloadOffset), size) : std::string_view(reinterpret_cast<const char *>(payloadOffset));
|
auto view{size ? std::string_view(reinterpret_cast<const char *>(payloadOffset), size) : std::string_view(reinterpret_cast<const char *>(payloadOffset))};
|
||||||
payloadOffset += view.length();
|
payloadOffset += view.length();
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@ -280,7 +280,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
inline void Push(const ValueType &value) {
|
inline void Push(const ValueType &value) {
|
||||||
auto size = payload.size();
|
auto size{payload.size()};
|
||||||
payload.resize(size + sizeof(ValueType));
|
payload.resize(size + sizeof(ValueType));
|
||||||
|
|
||||||
std::memcpy(payload.data() + size, reinterpret_cast<const u8 *>(&value), sizeof(ValueType));
|
std::memcpy(payload.data() + size, reinterpret_cast<const u8 *>(&value), sizeof(ValueType));
|
||||||
@ -292,7 +292,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
inline void Push(const std::string &string) {
|
inline void Push(const std::string &string) {
|
||||||
auto size = payload.size();
|
auto size{payload.size()};
|
||||||
payload.resize(size + string.size());
|
payload.resize(size + string.size());
|
||||||
|
|
||||||
std::memcpy(payload.data() + size, string.data(), string.size());
|
std::memcpy(payload.data() + size, string.data(), string.size());
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
namespace skyline::kernel {
|
namespace skyline::kernel {
|
||||||
ChunkDescriptor *MemoryManager::GetChunk(u64 address) {
|
ChunkDescriptor *MemoryManager::GetChunk(u64 address) {
|
||||||
auto chunk = std::upper_bound(chunkList.begin(), chunkList.end(), address, [](const u64 address, const ChunkDescriptor &chunk) -> bool {
|
auto chunk{std::upper_bound(chunkList.begin(), chunkList.end(), address, [](const u64 address, const ChunkDescriptor &chunk) -> bool {
|
||||||
return address < chunk.address;
|
return address < chunk.address;
|
||||||
});
|
})};
|
||||||
|
|
||||||
if (chunk-- != chunkList.begin()) {
|
if (chunk-- != chunkList.begin()) {
|
||||||
if ((chunk->address + chunk->size) > address)
|
if ((chunk->address + chunk->size) > address)
|
||||||
@ -23,9 +23,9 @@ namespace skyline::kernel {
|
|||||||
chunk = GetChunk(address);
|
chunk = GetChunk(address);
|
||||||
|
|
||||||
if (chunk) {
|
if (chunk) {
|
||||||
auto block = std::upper_bound(chunk->blockList.begin(), chunk->blockList.end(), address, [](const u64 address, const BlockDescriptor &block) -> bool {
|
auto block{std::upper_bound(chunk->blockList.begin(), chunk->blockList.end(), address, [](const u64 address, const BlockDescriptor &block) -> bool {
|
||||||
return address < block.address;
|
return address < block.address;
|
||||||
});
|
})};
|
||||||
|
|
||||||
if (block-- != chunk->blockList.begin()) {
|
if (block-- != chunk->blockList.begin()) {
|
||||||
if ((block->address + block->size) > address)
|
if ((block->address + block->size) > address)
|
||||||
@ -37,12 +37,12 @@ namespace skyline::kernel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::InsertChunk(const ChunkDescriptor &chunk) {
|
void MemoryManager::InsertChunk(const ChunkDescriptor &chunk) {
|
||||||
auto upperChunk = std::upper_bound(chunkList.begin(), chunkList.end(), chunk.address, [](const u64 address, const ChunkDescriptor &chunk) -> bool {
|
auto upperChunk{std::upper_bound(chunkList.begin(), chunkList.end(), chunk.address, [](const u64 address, const ChunkDescriptor &chunk) -> bool {
|
||||||
return address < chunk.address;
|
return address < chunk.address;
|
||||||
});
|
})};
|
||||||
|
|
||||||
if (upperChunk != chunkList.begin()) {
|
if (upperChunk != chunkList.begin()) {
|
||||||
auto lowerChunk = std::prev(upperChunk);
|
auto lowerChunk{std::prev(upperChunk)};
|
||||||
|
|
||||||
if (lowerChunk->address + lowerChunk->size > chunk.address)
|
if (lowerChunk->address + lowerChunk->size > chunk.address)
|
||||||
throw exception("InsertChunk: Descriptors are colliding: 0x{:X} - 0x{:X} and 0x{:X} - 0x{:X}", lowerChunk->address, lowerChunk->address + lowerChunk->size, chunk.address, chunk.address + chunk.size);
|
throw exception("InsertChunk: Descriptors are colliding: 0x{:X} - 0x{:X} and 0x{:X} - 0x{:X}", lowerChunk->address, lowerChunk->address + lowerChunk->size, chunk.address, chunk.address + chunk.size);
|
||||||
@ -52,7 +52,7 @@ namespace skyline::kernel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::DeleteChunk(u64 address) {
|
void MemoryManager::DeleteChunk(u64 address) {
|
||||||
for (auto chunk = chunkList.begin(), end = chunkList.end(); chunk != end;) {
|
for (auto chunk{chunkList.begin()}, end{chunkList.end()}; chunk != end;) {
|
||||||
if (chunk->address <= address && (chunk->address + chunk->size) > address)
|
if (chunk->address <= address && (chunk->address + chunk->size) > address)
|
||||||
chunk = chunkList.erase(chunk);
|
chunk = chunkList.erase(chunk);
|
||||||
else
|
else
|
||||||
@ -64,8 +64,8 @@ namespace skyline::kernel {
|
|||||||
if (chunk->blockList.size() == 1) {
|
if (chunk->blockList.size() == 1) {
|
||||||
chunk->blockList.begin()->size = size;
|
chunk->blockList.begin()->size = size;
|
||||||
} else if (size > chunk->size) {
|
} else if (size > chunk->size) {
|
||||||
auto begin = chunk->blockList.begin();
|
auto begin{chunk->blockList.begin()};
|
||||||
auto end = std::prev(chunk->blockList.end());
|
auto end{std::prev(chunk->blockList.end())};
|
||||||
|
|
||||||
BlockDescriptor block{
|
BlockDescriptor block{
|
||||||
.address = (end->address + end->size),
|
.address = (end->address + end->size),
|
||||||
@ -76,16 +76,16 @@ namespace skyline::kernel {
|
|||||||
|
|
||||||
chunk->blockList.push_back(block);
|
chunk->blockList.push_back(block);
|
||||||
} else if (size < chunk->size) {
|
} else if (size < chunk->size) {
|
||||||
auto endAddress = chunk->address + size;
|
auto endAddress{chunk->address + size};
|
||||||
|
|
||||||
for (auto block = chunk->blockList.begin(), end = chunk->blockList.end(); block != end;) {
|
for (auto block{chunk->blockList.begin()}, end{chunk->blockList.end()}; block != end;) {
|
||||||
if (block->address > endAddress)
|
if (block->address > endAddress)
|
||||||
block = chunk->blockList.erase(block);
|
block = chunk->blockList.erase(block);
|
||||||
else
|
else
|
||||||
block++;
|
block++;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto end = std::prev(chunk->blockList.end());
|
auto end{std::prev(chunk->blockList.end())};
|
||||||
end->size = endAddress - end->address;
|
end->size = endAddress - end->address;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,14 +96,14 @@ namespace skyline::kernel {
|
|||||||
if (chunk->address + chunk->size < block.address + block.size)
|
if (chunk->address + chunk->size < block.address + block.size)
|
||||||
throw exception("InsertBlock: Inserting block past chunk end is not allowed");
|
throw exception("InsertBlock: Inserting block past chunk end is not allowed");
|
||||||
|
|
||||||
for (auto iter = chunk->blockList.begin(); iter != chunk->blockList.end(); iter++) {
|
for (auto iter{chunk->blockList.begin()}; iter != chunk->blockList.end(); iter++) {
|
||||||
if (iter->address <= block.address) {
|
if (iter->address <= block.address) {
|
||||||
if ((iter->address + iter->size) > block.address) {
|
if ((iter->address + iter->size) > block.address) {
|
||||||
if (iter->address == block.address && iter->size == block.size) {
|
if (iter->address == block.address && iter->size == block.size) {
|
||||||
iter->attributes = block.attributes;
|
iter->attributes = block.attributes;
|
||||||
iter->permission = block.permission;
|
iter->permission = block.permission;
|
||||||
} else {
|
} else {
|
||||||
auto endBlock = *iter;
|
auto endBlock{*iter};
|
||||||
endBlock.address = (block.address + block.size);
|
endBlock.address = (block.address + block.size);
|
||||||
endBlock.size = (iter->address + iter->size) - endBlock.address;
|
endBlock.size = (iter->address + iter->size) - endBlock.address;
|
||||||
|
|
||||||
@ -169,16 +169,16 @@ namespace skyline::kernel {
|
|||||||
MemoryManager::MemoryManager(const DeviceState &state) : state(state) {}
|
MemoryManager::MemoryManager(const DeviceState &state) : state(state) {}
|
||||||
|
|
||||||
std::optional<DescriptorPack> MemoryManager::Get(u64 address, bool requireMapped) {
|
std::optional<DescriptorPack> MemoryManager::Get(u64 address, bool requireMapped) {
|
||||||
auto chunk = GetChunk(address);
|
auto chunk{GetChunk(address)};
|
||||||
|
|
||||||
if (chunk)
|
if (chunk)
|
||||||
return DescriptorPack{*GetBlock(address, chunk), *chunk};
|
return DescriptorPack{*GetBlock(address, chunk), *chunk};
|
||||||
|
|
||||||
// If the requested address is in the address space but no chunks are present then we return a new unmapped region
|
// If the requested address is in the address space but no chunks are present then we return a new unmapped region
|
||||||
if (addressSpace.IsInside(address) && !requireMapped) {
|
if (addressSpace.IsInside(address) && !requireMapped) {
|
||||||
auto upperChunk = std::upper_bound(chunkList.begin(), chunkList.end(), address, [](const u64 address, const ChunkDescriptor &chunk) -> bool {
|
auto upperChunk{std::upper_bound(chunkList.begin(), chunkList.end(), address, [](const u64 address, const ChunkDescriptor &chunk) -> bool {
|
||||||
return address < chunk.address;
|
return address < chunk.address;
|
||||||
});
|
})};
|
||||||
|
|
||||||
u64 upperAddress{};
|
u64 upperAddress{};
|
||||||
u64 lowerAddress{};
|
u64 lowerAddress{};
|
||||||
@ -197,7 +197,7 @@ namespace skyline::kernel {
|
|||||||
lowerAddress = chunkList.back().address + chunkList.back().size;
|
lowerAddress = chunkList.back().address + chunkList.back().size;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 size = upperAddress - lowerAddress;
|
u64 size{upperAddress - lowerAddress};
|
||||||
|
|
||||||
return DescriptorPack{
|
return DescriptorPack{
|
||||||
.chunk = {
|
.chunk = {
|
||||||
@ -216,11 +216,9 @@ namespace skyline::kernel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t MemoryManager::GetProgramSize() {
|
size_t MemoryManager::GetProgramSize() {
|
||||||
size_t size = 0;
|
size_t size{};
|
||||||
|
|
||||||
for (const auto &chunk : chunkList)
|
for (const auto &chunk : chunkList)
|
||||||
size += chunk.size;
|
size += chunk.size;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ namespace skyline {
|
|||||||
* @return The value of the permission struct in Linux format
|
* @return The value of the permission struct in Linux format
|
||||||
*/
|
*/
|
||||||
constexpr int Get() const {
|
constexpr int Get() const {
|
||||||
int perm = 0;
|
int perm{};
|
||||||
if (r)
|
if (r)
|
||||||
perm |= PROT_READ;
|
perm |= PROT_READ;
|
||||||
if (w)
|
if (w)
|
||||||
@ -145,27 +145,27 @@ namespace skyline {
|
|||||||
* @brief The preset states that different regions are set to (https://switchbrew.org/wiki/SVC#MemoryType)
|
* @brief The preset states that different regions are set to (https://switchbrew.org/wiki/SVC#MemoryType)
|
||||||
*/
|
*/
|
||||||
namespace states {
|
namespace states {
|
||||||
constexpr MemoryState Unmapped = 0x00000000;
|
constexpr MemoryState Unmapped{0x00000000};
|
||||||
constexpr MemoryState Io = 0x00002001;
|
constexpr MemoryState Io{0x00002001};
|
||||||
constexpr MemoryState CodeStatic = 0x00DC7E03;
|
constexpr MemoryState CodeStatic{0x00DC7E03};
|
||||||
constexpr MemoryState CodeMutable = 0x03FEBD04;
|
constexpr MemoryState CodeMutable{0x03FEBD04};
|
||||||
constexpr MemoryState Heap = 0x037EBD05;
|
constexpr MemoryState Heap{0x037EBD05};
|
||||||
constexpr MemoryState SharedMemory = 0x00402006;
|
constexpr MemoryState SharedMemory{0x00402006};
|
||||||
constexpr MemoryState Alias = 0x00482907;
|
constexpr MemoryState Alias{0x00482907};
|
||||||
constexpr MemoryState AliasCode = 0x00DD7E08;
|
constexpr MemoryState AliasCode{0x00DD7E08};
|
||||||
constexpr MemoryState AliasCodeData = 0x03FFBD09;
|
constexpr MemoryState AliasCodeData{0x03FFBD09};
|
||||||
constexpr MemoryState Ipc = 0x005C3C0A;
|
constexpr MemoryState Ipc{0x005C3C0A};
|
||||||
constexpr MemoryState Stack = 0x005C3C0B;
|
constexpr MemoryState Stack{0x005C3C0B};
|
||||||
constexpr MemoryState ThreadLocal = 0x0040200C;
|
constexpr MemoryState ThreadLocal{0x0040200C};
|
||||||
constexpr MemoryState TransferMemoryIsolated = 0x015C3C0D;
|
constexpr MemoryState TransferMemoryIsolated{0x015C3C0D};
|
||||||
constexpr MemoryState TransferMemory = 0x005C380E;
|
constexpr MemoryState TransferMemory{0x005C380E};
|
||||||
constexpr MemoryState SharedCode = 0x0040380F;
|
constexpr MemoryState SharedCode{0x0040380F};
|
||||||
constexpr MemoryState Reserved = 0x00000010;
|
constexpr MemoryState Reserved{0x00000010};
|
||||||
constexpr MemoryState NonSecureIpc = 0x005C3811;
|
constexpr MemoryState NonSecureIpc{0x005C3811};
|
||||||
constexpr MemoryState NonDeviceIpc = 0x004C2812;
|
constexpr MemoryState NonDeviceIpc{0x004C2812};
|
||||||
constexpr MemoryState KernelStack = 0x00002013;
|
constexpr MemoryState KernelStack{0x00002013};
|
||||||
constexpr MemoryState CodeReadOnly = 0x00402214;
|
constexpr MemoryState CodeReadOnly{0x00402214};
|
||||||
constexpr MemoryState CodeWritable = 0x00402015;
|
constexpr MemoryState CodeWritable{0x00402015};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace skyline::kernel::svc {
|
namespace skyline::kernel::svc {
|
||||||
void SetHeapSize(DeviceState &state) {
|
void SetHeapSize(DeviceState &state) {
|
||||||
auto size = state.ctx->registers.w1;
|
auto size{state.ctx->registers.w1};
|
||||||
|
|
||||||
if (!util::IsAligned(size, 0x200000)) {
|
if (!util::IsAligned(size, 0x200000)) {
|
||||||
state.ctx->registers.w0 = result::InvalidSize;
|
state.ctx->registers.w0 = result::InvalidSize;
|
||||||
@ -17,7 +17,7 @@ namespace skyline::kernel::svc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &heap = state.process->heap;
|
auto &heap{state.process->heap};
|
||||||
heap->Resize(size);
|
heap->Resize(size);
|
||||||
|
|
||||||
state.ctx->registers.w0 = Result{};
|
state.ctx->registers.w0 = Result{};
|
||||||
@ -27,14 +27,14 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetMemoryAttribute(DeviceState &state) {
|
void SetMemoryAttribute(DeviceState &state) {
|
||||||
auto address = state.ctx->registers.x0;
|
auto address{state.ctx->registers.x0};
|
||||||
if (!util::PageAligned(address)) {
|
if (!util::PageAligned(address)) {
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
state.logger->Warn("svcSetMemoryAttribute: 'address' not page aligned: 0x{:X}", address);
|
state.logger->Warn("svcSetMemoryAttribute: 'address' not page aligned: 0x{:X}", address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto size = state.ctx->registers.x1;
|
auto size{state.ctx->registers.x1};
|
||||||
if (!util::PageAligned(size)) {
|
if (!util::PageAligned(size)) {
|
||||||
state.ctx->registers.w0 = result::InvalidSize;
|
state.ctx->registers.w0 = result::InvalidSize;
|
||||||
state.logger->Warn("svcSetMemoryAttribute: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
|
state.logger->Warn("svcSetMemoryAttribute: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
|
||||||
@ -44,15 +44,15 @@ namespace skyline::kernel::svc {
|
|||||||
memory::MemoryAttribute mask{.value = state.ctx->registers.w2};
|
memory::MemoryAttribute mask{.value = state.ctx->registers.w2};
|
||||||
memory::MemoryAttribute value{.value = state.ctx->registers.w3};
|
memory::MemoryAttribute value{.value = state.ctx->registers.w3};
|
||||||
|
|
||||||
auto maskedValue = mask.value | value.value;
|
auto maskedValue{mask.value | value.value};
|
||||||
if (maskedValue != mask.value || !mask.isUncached || mask.isDeviceShared || mask.isBorrowed || mask.isIpcLocked) {
|
if (maskedValue != mask.value || !mask.isUncached || mask.isDeviceShared || mask.isBorrowed || mask.isIpcLocked) {
|
||||||
state.ctx->registers.w0 = result::InvalidCombination;
|
state.ctx->registers.w0 = result::InvalidCombination;
|
||||||
state.logger->Warn("svcSetMemoryAttribute: 'mask' invalid: 0x{:X}, 0x{:X}", mask.value, value.value);
|
state.logger->Warn("svcSetMemoryAttribute: 'mask' invalid: 0x{:X}, 0x{:X}", mask.value, value.value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto chunk = state.os->memory.GetChunk(address);
|
auto chunk{state.os->memory.GetChunk(address)};
|
||||||
auto block = state.os->memory.GetBlock(address);
|
auto block{state.os->memory.GetBlock(address)};
|
||||||
if (!chunk || !block) {
|
if (!chunk || !block) {
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
state.logger->Warn("svcSetMemoryAttribute: Cannot find memory region: 0x{:X}", address);
|
state.logger->Warn("svcSetMemoryAttribute: Cannot find memory region: 0x{:X}", address);
|
||||||
@ -73,9 +73,9 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MapMemory(DeviceState &state) {
|
void MapMemory(DeviceState &state) {
|
||||||
auto destination = state.ctx->registers.x0;
|
auto destination{state.ctx->registers.x0};
|
||||||
auto source = state.ctx->registers.x1;
|
auto source{state.ctx->registers.x1};
|
||||||
auto size = state.ctx->registers.x2;
|
auto size{state.ctx->registers.x2};
|
||||||
|
|
||||||
if (!util::PageAligned(destination) || !util::PageAligned(source)) {
|
if (!util::PageAligned(destination) || !util::PageAligned(source)) {
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
@ -89,14 +89,14 @@ namespace skyline::kernel::svc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto stack = state.os->memory.stack;
|
auto stack{state.os->memory.stack};
|
||||||
if (!stack.IsInside(destination)) {
|
if (!stack.IsInside(destination)) {
|
||||||
state.ctx->registers.w0 = result::InvalidMemoryRegion;
|
state.ctx->registers.w0 = result::InvalidMemoryRegion;
|
||||||
state.logger->Warn("svcMapMemory: Destination not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
|
state.logger->Warn("svcMapMemory: Destination not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto descriptor = state.os->memory.Get(source);
|
auto descriptor{state.os->memory.Get(source)};
|
||||||
if (!descriptor) {
|
if (!descriptor) {
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
state.logger->Warn("svcMapMemory: Source has no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
|
state.logger->Warn("svcMapMemory: Source has no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
|
||||||
@ -111,7 +111,7 @@ namespace skyline::kernel::svc {
|
|||||||
state.process->NewHandle<type::KPrivateMemory>(destination, size, descriptor->block.permission, memory::states::Stack);
|
state.process->NewHandle<type::KPrivateMemory>(destination, size, descriptor->block.permission, memory::states::Stack);
|
||||||
state.process->CopyMemory(source, destination, size);
|
state.process->CopyMemory(source, destination, size);
|
||||||
|
|
||||||
auto object = state.process->GetMemoryObject(source);
|
auto object{state.process->GetMemoryObject(source)};
|
||||||
if (!object)
|
if (!object)
|
||||||
throw exception("svcMapMemory: Cannot find memory object in handle table for address 0x{:X}", source);
|
throw exception("svcMapMemory: Cannot find memory object in handle table for address 0x{:X}", source);
|
||||||
object->item->UpdatePermission(source, size, {false, false, false});
|
object->item->UpdatePermission(source, size, {false, false, false});
|
||||||
@ -121,9 +121,9 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UnmapMemory(DeviceState &state) {
|
void UnmapMemory(DeviceState &state) {
|
||||||
auto source = state.ctx->registers.x0;
|
auto source{state.ctx->registers.x0};
|
||||||
auto destination = state.ctx->registers.x1;
|
auto destination{state.ctx->registers.x1};
|
||||||
auto size = state.ctx->registers.x2;
|
auto size{state.ctx->registers.x2};
|
||||||
|
|
||||||
if (!util::PageAligned(destination) || !util::PageAligned(source)) {
|
if (!util::PageAligned(destination) || !util::PageAligned(source)) {
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
@ -137,15 +137,15 @@ namespace skyline::kernel::svc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto stack = state.os->memory.stack;
|
auto stack{state.os->memory.stack};
|
||||||
if (!stack.IsInside(source)) {
|
if (!stack.IsInside(source)) {
|
||||||
state.ctx->registers.w0 = result::InvalidMemoryRegion;
|
state.ctx->registers.w0 = result::InvalidMemoryRegion;
|
||||||
state.logger->Warn("svcUnmapMemory: Source not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
|
state.logger->Warn("svcUnmapMemory: Source not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sourceDesc = state.os->memory.Get(source);
|
auto sourceDesc{state.os->memory.Get(source)};
|
||||||
auto destDesc = state.os->memory.Get(destination);
|
auto destDesc{state.os->memory.Get(destination)};
|
||||||
if (!sourceDesc || !destDesc) {
|
if (!sourceDesc || !destDesc) {
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
state.logger->Warn("svcUnmapMemory: Addresses have no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
|
state.logger->Warn("svcUnmapMemory: Addresses have no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
|
||||||
@ -158,7 +158,7 @@ namespace skyline::kernel::svc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto destObject = state.process->GetMemoryObject(destination);
|
auto destObject{state.process->GetMemoryObject(destination)};
|
||||||
if (!destObject)
|
if (!destObject)
|
||||||
throw exception("svcUnmapMemory: Cannot find destination memory object in handle table for address 0x{:X}", destination);
|
throw exception("svcUnmapMemory: Cannot find destination memory object in handle table for address 0x{:X}", destination);
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ namespace skyline::kernel::svc {
|
|||||||
|
|
||||||
state.process->CopyMemory(destination, source, size);
|
state.process->CopyMemory(destination, source, size);
|
||||||
|
|
||||||
auto sourceObject = state.process->GetMemoryObject(destination);
|
auto sourceObject{state.process->GetMemoryObject(destination)};
|
||||||
if (!sourceObject)
|
if (!sourceObject)
|
||||||
throw exception("svcUnmapMemory: Cannot find source memory object in handle table for address 0x{:X}", source);
|
throw exception("svcUnmapMemory: Cannot find source memory object in handle table for address 0x{:X}", source);
|
||||||
|
|
||||||
@ -179,8 +179,8 @@ namespace skyline::kernel::svc {
|
|||||||
void QueryMemory(DeviceState &state) {
|
void QueryMemory(DeviceState &state) {
|
||||||
memory::MemoryInfo memInfo{};
|
memory::MemoryInfo memInfo{};
|
||||||
|
|
||||||
auto address = state.ctx->registers.x2;
|
auto address{state.ctx->registers.x2};
|
||||||
auto descriptor = state.os->memory.Get(address, false);
|
auto descriptor{state.os->memory.Get(address, false)};
|
||||||
|
|
||||||
if (descriptor) {
|
if (descriptor) {
|
||||||
memInfo = {
|
memInfo = {
|
||||||
@ -195,7 +195,7 @@ namespace skyline::kernel::svc {
|
|||||||
|
|
||||||
state.logger->Debug("svcQueryMemory: Address: 0x{:X}, Size: 0x{:X}, Type: 0x{:X}, Is Uncached: {}, Permissions: {}{}{}", memInfo.address, memInfo.size, memInfo.type, static_cast<bool>(descriptor->block.attributes.isUncached), descriptor->block.permission.r ? "R" : "-", descriptor->block.permission.w ? "W" : "-", descriptor->block.permission.x ? "X" : "-");
|
state.logger->Debug("svcQueryMemory: Address: 0x{:X}, Size: 0x{:X}, Type: 0x{:X}, Is Uncached: {}, Permissions: {}{}{}", memInfo.address, memInfo.size, memInfo.type, static_cast<bool>(descriptor->block.attributes.isUncached), descriptor->block.permission.r ? "R" : "-", descriptor->block.permission.w ? "W" : "-", descriptor->block.permission.x ? "X" : "-");
|
||||||
} else {
|
} else {
|
||||||
auto addressSpaceEnd = state.os->memory.addressSpace.address + state.os->memory.addressSpace.size;
|
auto addressSpaceEnd{state.os->memory.addressSpace.address + state.os->memory.addressSpace.size};
|
||||||
|
|
||||||
memInfo = {
|
memInfo = {
|
||||||
.address = addressSpaceEnd,
|
.address = addressSpaceEnd,
|
||||||
@ -217,10 +217,10 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CreateThread(DeviceState &state) {
|
void CreateThread(DeviceState &state) {
|
||||||
auto entryAddress = state.ctx->registers.x1;
|
auto entryAddress{state.ctx->registers.x1};
|
||||||
auto entryArgument = state.ctx->registers.x2;
|
auto entryArgument{state.ctx->registers.x2};
|
||||||
auto stackTop = state.ctx->registers.x3;
|
auto stackTop{state.ctx->registers.x3};
|
||||||
auto priority = static_cast<i8>(state.ctx->registers.w4);
|
auto priority{static_cast<i8>(state.ctx->registers.w4)};
|
||||||
|
|
||||||
if (!state.thread->switchPriority.Valid(priority)) {
|
if (!state.thread->switchPriority.Valid(priority)) {
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
@ -228,7 +228,7 @@ namespace skyline::kernel::svc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto thread = state.process->CreateThread(entryAddress, entryArgument, stackTop, priority);
|
auto thread{state.process->CreateThread(entryAddress, entryArgument, stackTop, priority)};
|
||||||
state.logger->Debug("svcCreateThread: Created thread with handle 0x{:X} (Entry Point: 0x{:X}, Argument: 0x{:X}, Stack Pointer: 0x{:X}, Priority: {}, TID: {})", thread->handle, entryAddress, entryArgument, stackTop, priority, thread->tid);
|
state.logger->Debug("svcCreateThread: Created thread with handle 0x{:X} (Entry Point: 0x{:X}, Argument: 0x{:X}, Stack Pointer: 0x{:X}, Priority: {}, TID: {})", thread->handle, entryAddress, entryArgument, stackTop, priority, thread->tid);
|
||||||
|
|
||||||
state.ctx->registers.w1 = thread->handle;
|
state.ctx->registers.w1 = thread->handle;
|
||||||
@ -236,9 +236,9 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StartThread(DeviceState &state) {
|
void StartThread(DeviceState &state) {
|
||||||
auto handle = state.ctx->registers.w0;
|
auto handle{state.ctx->registers.w0};
|
||||||
try {
|
try {
|
||||||
auto thread = state.process->GetHandle<type::KThread>(handle);
|
auto thread{state.process->GetHandle<type::KThread>(handle)};
|
||||||
state.logger->Debug("svcStartThread: Starting thread: 0x{:X}, PID: {}", handle, thread->tid);
|
state.logger->Debug("svcStartThread: Starting thread: 0x{:X}, PID: {}", handle, thread->tid);
|
||||||
thread->Start();
|
thread->Start();
|
||||||
state.ctx->registers.w0 = Result{};
|
state.ctx->registers.w0 = Result{};
|
||||||
@ -254,7 +254,7 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SleepThread(DeviceState &state) {
|
void SleepThread(DeviceState &state) {
|
||||||
auto in = state.ctx->registers.x0;
|
auto in{state.ctx->registers.x0};
|
||||||
|
|
||||||
switch (in) {
|
switch (in) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -264,7 +264,7 @@ namespace skyline::kernel::svc {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
state.logger->Debug("svcSleepThread: Thread sleeping for {} ns", in);
|
state.logger->Debug("svcSleepThread: Thread sleeping for {} ns", in);
|
||||||
struct timespec spec = {
|
struct timespec spec{
|
||||||
.tv_sec = static_cast<time_t>(state.ctx->registers.x0 / 1000000000),
|
.tv_sec = static_cast<time_t>(state.ctx->registers.x0 / 1000000000),
|
||||||
.tv_nsec = static_cast<long>(state.ctx->registers.x0 % 1000000000)
|
.tv_nsec = static_cast<long>(state.ctx->registers.x0 % 1000000000)
|
||||||
};
|
};
|
||||||
@ -273,9 +273,9 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GetThreadPriority(DeviceState &state) {
|
void GetThreadPriority(DeviceState &state) {
|
||||||
auto handle = state.ctx->registers.w1;
|
auto handle{state.ctx->registers.w1};
|
||||||
try {
|
try {
|
||||||
auto priority = state.process->GetHandle<type::KThread>(handle)->priority;
|
auto priority{state.process->GetHandle<type::KThread>(handle)->priority};
|
||||||
state.logger->Debug("svcGetThreadPriority: Writing thread priority {}", priority);
|
state.logger->Debug("svcGetThreadPriority: Writing thread priority {}", priority);
|
||||||
|
|
||||||
state.ctx->registers.w1 = priority;
|
state.ctx->registers.w1 = priority;
|
||||||
@ -287,8 +287,8 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetThreadPriority(DeviceState &state) {
|
void SetThreadPriority(DeviceState &state) {
|
||||||
auto handle = state.ctx->registers.w0;
|
auto handle{state.ctx->registers.w0};
|
||||||
auto priority = state.ctx->registers.w1;
|
auto priority{state.ctx->registers.w1};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
state.logger->Debug("svcSetThreadPriority: Setting thread priority to {}", priority);
|
state.logger->Debug("svcSetThreadPriority: Setting thread priority to {}", priority);
|
||||||
@ -301,15 +301,15 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClearEvent(DeviceState &state) {
|
void ClearEvent(DeviceState &state) {
|
||||||
auto object = state.process->GetHandle<type::KEvent>(state.ctx->registers.w0);
|
auto object{state.process->GetHandle<type::KEvent>(state.ctx->registers.w0)};
|
||||||
object->signalled = false;
|
object->signalled = false;
|
||||||
state.ctx->registers.w0 = Result{};
|
state.ctx->registers.w0 = Result{};
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapSharedMemory(DeviceState &state) {
|
void MapSharedMemory(DeviceState &state) {
|
||||||
try {
|
try {
|
||||||
auto object = state.process->GetHandle<type::KSharedMemory>(state.ctx->registers.w0);
|
auto object{state.process->GetHandle<type::KSharedMemory>(state.ctx->registers.w0)};
|
||||||
auto address = state.ctx->registers.x1;
|
auto address{state.ctx->registers.x1};
|
||||||
|
|
||||||
if (!util::PageAligned(address)) {
|
if (!util::PageAligned(address)) {
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
@ -317,14 +317,14 @@ namespace skyline::kernel::svc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto size = state.ctx->registers.x2;
|
auto size{state.ctx->registers.x2};
|
||||||
if (!util::PageAligned(size)) {
|
if (!util::PageAligned(size)) {
|
||||||
state.ctx->registers.w0 = result::InvalidSize;
|
state.ctx->registers.w0 = result::InvalidSize;
|
||||||
state.logger->Warn("svcMapSharedMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
|
state.logger->Warn("svcMapSharedMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory::Permission permission = *reinterpret_cast<memory::Permission *>(&state.ctx->registers.w3);
|
memory::Permission permission{*reinterpret_cast<memory::Permission *>(&state.ctx->registers.w3)};
|
||||||
if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
|
if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
|
||||||
state.logger->Warn("svcMapSharedMemory: 'permission' invalid: {}{}{}", permission.r ? "R" : "-", permission.w ? "W" : "-", permission.x ? "X" : "-");
|
state.logger->Warn("svcMapSharedMemory: 'permission' invalid: {}{}{}", permission.r ? "R" : "-", permission.w ? "W" : "-", permission.x ? "X" : "-");
|
||||||
state.ctx->registers.w0 = result::InvalidNewMemoryPermission;
|
state.ctx->registers.w0 = result::InvalidNewMemoryPermission;
|
||||||
@ -343,21 +343,21 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CreateTransferMemory(DeviceState &state) {
|
void CreateTransferMemory(DeviceState &state) {
|
||||||
auto address = state.ctx->registers.x1;
|
auto address{state.ctx->registers.x1};
|
||||||
if (!util::PageAligned(address)) {
|
if (!util::PageAligned(address)) {
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
state.logger->Warn("svcCreateTransferMemory: 'address' not page aligned: 0x{:X}", address);
|
state.logger->Warn("svcCreateTransferMemory: 'address' not page aligned: 0x{:X}", address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto size = state.ctx->registers.x2;
|
auto size{state.ctx->registers.x2};
|
||||||
if (!util::PageAligned(size)) {
|
if (!util::PageAligned(size)) {
|
||||||
state.ctx->registers.w0 = result::InvalidSize;
|
state.ctx->registers.w0 = result::InvalidSize;
|
||||||
state.logger->Warn("svcCreateTransferMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
|
state.logger->Warn("svcCreateTransferMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory::Permission permission = *reinterpret_cast<memory::Permission *>(&state.ctx->registers.w3);
|
memory::Permission permission{*reinterpret_cast<memory::Permission *>(&state.ctx->registers.w3)};
|
||||||
if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
|
if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
|
||||||
state.logger->Warn("svcCreateTransferMemory: 'permission' invalid: {}{}{}", permission.r ? "R" : "-", permission.w ? "W" : "-", permission.x ? "X" : "-");
|
state.logger->Warn("svcCreateTransferMemory: 'permission' invalid: {}{}{}", permission.r ? "R" : "-", permission.w ? "W" : "-", permission.x ? "X" : "-");
|
||||||
state.ctx->registers.w0 = result::InvalidNewMemoryPermission;
|
state.ctx->registers.w0 = result::InvalidNewMemoryPermission;
|
||||||
@ -366,14 +366,14 @@ namespace skyline::kernel::svc {
|
|||||||
|
|
||||||
state.logger->Debug("svcCreateTransferMemory: Creating transfer memory at 0x{:X} for {} bytes ({}{}{})", address, size, permission.r ? "R" : "-", permission.w ? "W" : "-", permission.x ? "X" : "-");
|
state.logger->Debug("svcCreateTransferMemory: Creating transfer memory at 0x{:X} for {} bytes ({}{}{})", address, size, permission.r ? "R" : "-", permission.w ? "W" : "-", permission.x ? "X" : "-");
|
||||||
|
|
||||||
auto shmem = state.process->NewHandle<type::KTransferMemory>(state.process->pid, address, size, permission);
|
auto shmem{state.process->NewHandle<type::KTransferMemory>(state.process->pid, address, size, permission)};
|
||||||
|
|
||||||
state.ctx->registers.w0 = Result{};
|
state.ctx->registers.w0 = Result{};
|
||||||
state.ctx->registers.w1 = shmem.handle;
|
state.ctx->registers.w1 = shmem.handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseHandle(DeviceState &state) {
|
void CloseHandle(DeviceState &state) {
|
||||||
auto handle = static_cast<KHandle>(state.ctx->registers.w0);
|
auto handle{static_cast<KHandle>(state.ctx->registers.w0)};
|
||||||
try {
|
try {
|
||||||
state.process->DeleteHandle(handle);
|
state.process->DeleteHandle(handle);
|
||||||
state.logger->Debug("svcCloseHandle: Closing handle: 0x{:X}", handle);
|
state.logger->Debug("svcCloseHandle: Closing handle: 0x{:X}", handle);
|
||||||
@ -385,9 +385,9 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ResetSignal(DeviceState &state) {
|
void ResetSignal(DeviceState &state) {
|
||||||
auto handle = state.ctx->registers.w0;
|
auto handle{state.ctx->registers.w0};
|
||||||
try {
|
try {
|
||||||
auto &object = state.process->handles.at(handle);
|
auto &object{state.process->handles.at(handle)};
|
||||||
switch (object->objectType) {
|
switch (object->objectType) {
|
||||||
case type::KType::KEvent:
|
case type::KType::KEvent:
|
||||||
std::static_pointer_cast<type::KEvent>(object)->ResetSignal();
|
std::static_pointer_cast<type::KEvent>(object)->ResetSignal();
|
||||||
@ -414,9 +414,9 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WaitSynchronization(DeviceState &state) {
|
void WaitSynchronization(DeviceState &state) {
|
||||||
constexpr auto maxSyncHandles = 0x40; // The total amount of handles that can be passed to WaitSynchronization
|
constexpr u8 maxSyncHandles{0x40}; // The total amount of handles that can be passed to WaitSynchronization
|
||||||
|
|
||||||
auto numHandles = state.ctx->registers.w2;
|
auto numHandles{state.ctx->registers.w2};
|
||||||
if (numHandles > maxSyncHandles) {
|
if (numHandles > maxSyncHandles) {
|
||||||
state.ctx->registers.w0 = result::OutOfHandles;
|
state.ctx->registers.w0 = result::OutOfHandles;
|
||||||
return;
|
return;
|
||||||
@ -431,7 +431,7 @@ namespace skyline::kernel::svc {
|
|||||||
for (const auto &handle : waitHandles) {
|
for (const auto &handle : waitHandles) {
|
||||||
handleStr += fmt::format("* 0x{:X}\n", handle);
|
handleStr += fmt::format("* 0x{:X}\n", handle);
|
||||||
|
|
||||||
auto object = state.process->handles.at(handle);
|
auto object{state.process->handles.at(handle)};
|
||||||
switch (object->objectType) {
|
switch (object->objectType) {
|
||||||
case type::KType::KProcess:
|
case type::KType::KProcess:
|
||||||
case type::KType::KThread:
|
case type::KType::KThread:
|
||||||
@ -448,10 +448,10 @@ namespace skyline::kernel::svc {
|
|||||||
objectTable.push_back(std::static_pointer_cast<type::KSyncObject>(object));
|
objectTable.push_back(std::static_pointer_cast<type::KSyncObject>(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto timeout = state.ctx->registers.x3;
|
auto timeout{state.ctx->registers.x3};
|
||||||
state.logger->Debug("svcWaitSynchronization: Waiting on handles:\n{}Timeout: 0x{:X} ns", handleStr, timeout);
|
state.logger->Debug("svcWaitSynchronization: Waiting on handles:\n{}Timeout: 0x{:X} ns", handleStr, timeout);
|
||||||
|
|
||||||
auto start = util::GetTimeNs();
|
auto start{util::GetTimeNs()};
|
||||||
while (true) {
|
while (true) {
|
||||||
if (state.thread->cancelSync) {
|
if (state.thread->cancelSync) {
|
||||||
state.thread->cancelSync = false;
|
state.thread->cancelSync = false;
|
||||||
@ -488,15 +488,15 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ArbitrateLock(DeviceState &state) {
|
void ArbitrateLock(DeviceState &state) {
|
||||||
auto address = state.ctx->registers.x1;
|
auto address{state.ctx->registers.x1};
|
||||||
if (!util::WordAligned(address)) {
|
if (!util::WordAligned(address)) {
|
||||||
state.logger->Warn("svcArbitrateLock: 'address' not word aligned: 0x{:X}", address);
|
state.logger->Warn("svcArbitrateLock: 'address' not word aligned: 0x{:X}", address);
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ownerHandle = state.ctx->registers.w0;
|
auto ownerHandle{state.ctx->registers.w0};
|
||||||
auto requesterHandle = state.ctx->registers.w2;
|
auto requesterHandle{state.ctx->registers.w2};
|
||||||
if (requesterHandle != state.thread->handle)
|
if (requesterHandle != state.thread->handle)
|
||||||
throw exception("svcWaitProcessWideKeyAtomic: Handle doesn't match current thread: 0x{:X} for thread 0x{:X}", requesterHandle, state.thread->handle);
|
throw exception("svcWaitProcessWideKeyAtomic: Handle doesn't match current thread: 0x{:X} for thread 0x{:X}", requesterHandle, state.thread->handle);
|
||||||
|
|
||||||
@ -511,7 +511,7 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ArbitrateUnlock(DeviceState &state) {
|
void ArbitrateUnlock(DeviceState &state) {
|
||||||
auto address = state.ctx->registers.x0;
|
auto address{state.ctx->registers.x0};
|
||||||
if (!util::WordAligned(address)) {
|
if (!util::WordAligned(address)) {
|
||||||
state.logger->Warn("svcArbitrateUnlock: 'address' not word aligned: 0x{:X}", address);
|
state.logger->Warn("svcArbitrateUnlock: 'address' not word aligned: 0x{:X}", address);
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
@ -530,15 +530,15 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WaitProcessWideKeyAtomic(DeviceState &state) {
|
void WaitProcessWideKeyAtomic(DeviceState &state) {
|
||||||
auto mtxAddress = state.ctx->registers.x0;
|
auto mtxAddress{state.ctx->registers.x0};
|
||||||
if (!util::WordAligned(mtxAddress)) {
|
if (!util::WordAligned(mtxAddress)) {
|
||||||
state.logger->Warn("svcWaitProcessWideKeyAtomic: mutex address not word aligned: 0x{:X}", mtxAddress);
|
state.logger->Warn("svcWaitProcessWideKeyAtomic: mutex address not word aligned: 0x{:X}", mtxAddress);
|
||||||
state.ctx->registers.w0 = result::InvalidAddress;
|
state.ctx->registers.w0 = result::InvalidAddress;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto condAddress = state.ctx->registers.x1;
|
auto condAddress{state.ctx->registers.x1};
|
||||||
auto handle = state.ctx->registers.w2;
|
auto handle{state.ctx->registers.w2};
|
||||||
if (handle != state.thread->handle)
|
if (handle != state.thread->handle)
|
||||||
throw exception("svcWaitProcessWideKeyAtomic: Handle doesn't match current thread: 0x{:X} for thread 0x{:X}", handle, state.thread->handle);
|
throw exception("svcWaitProcessWideKeyAtomic: Handle doesn't match current thread: 0x{:X} for thread 0x{:X}", handle, state.thread->handle);
|
||||||
|
|
||||||
@ -548,7 +548,7 @@ namespace skyline::kernel::svc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto timeout = state.ctx->registers.x3;
|
auto timeout{state.ctx->registers.x3};
|
||||||
state.logger->Debug("svcWaitProcessWideKeyAtomic: Mutex: 0x{:X}, Conditional-Variable: 0x{:X}, Timeout: {} ns", mtxAddress, condAddress, timeout);
|
state.logger->Debug("svcWaitProcessWideKeyAtomic: Mutex: 0x{:X}, Conditional-Variable: 0x{:X}, Timeout: {} ns", mtxAddress, condAddress, timeout);
|
||||||
|
|
||||||
if (state.process->ConditionalVariableWait(condAddress, mtxAddress, timeout)) {
|
if (state.process->ConditionalVariableWait(condAddress, mtxAddress, timeout)) {
|
||||||
@ -561,8 +561,8 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SignalProcessWideKey(DeviceState &state) {
|
void SignalProcessWideKey(DeviceState &state) {
|
||||||
auto address = state.ctx->registers.x0;
|
auto address{state.ctx->registers.x0};
|
||||||
auto count = state.ctx->registers.w1;
|
auto count{state.ctx->registers.w1};
|
||||||
|
|
||||||
state.logger->Debug("svcSignalProcessWideKey: Signalling Conditional-Variable at 0x{:X} for {}", address, count);
|
state.logger->Debug("svcSignalProcessWideKey: Signalling Conditional-Variable at 0x{:X} for {}", address, count);
|
||||||
state.process->ConditionalVariableSignal(address, count);
|
state.process->ConditionalVariableSignal(address, count);
|
||||||
@ -583,7 +583,7 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConnectToNamedPort(DeviceState &state) {
|
void ConnectToNamedPort(DeviceState &state) {
|
||||||
constexpr auto portSize = 0x8; //!< The size of a port name string
|
constexpr u8 portSize{0x8}; //!< The size of a port name string
|
||||||
std::string_view port(state.process->GetPointer<char>(state.ctx->registers.x1), portSize);
|
std::string_view port(state.process->GetPointer<char>(state.ctx->registers.x1), portSize);
|
||||||
|
|
||||||
KHandle handle{};
|
KHandle handle{};
|
||||||
@ -607,8 +607,8 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GetThreadId(DeviceState &state) {
|
void GetThreadId(DeviceState &state) {
|
||||||
constexpr KHandle threadSelf = 0xFFFF8000; // This is the handle used by threads to refer to themselves
|
constexpr KHandle threadSelf{0xFFFF8000}; // This is the handle used by threads to refer to themselves
|
||||||
auto handle = state.ctx->registers.w1;
|
auto handle{state.ctx->registers.w1};
|
||||||
pid_t pid{};
|
pid_t pid{};
|
||||||
|
|
||||||
if (handle != threadSelf)
|
if (handle != threadSelf)
|
||||||
@ -623,7 +623,7 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OutputDebugString(DeviceState &state) {
|
void OutputDebugString(DeviceState &state) {
|
||||||
auto debug = state.process->GetString(state.ctx->registers.x0, state.ctx->registers.x1);
|
auto debug{state.process->GetString(state.ctx->registers.x0, state.ctx->registers.x1)};
|
||||||
|
|
||||||
if (debug.back() == '\n')
|
if (debug.back() == '\n')
|
||||||
debug.pop_back();
|
debug.pop_back();
|
||||||
@ -633,13 +633,13 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GetInfo(DeviceState &state) {
|
void GetInfo(DeviceState &state) {
|
||||||
auto id0 = state.ctx->registers.w1;
|
auto id0{state.ctx->registers.w1};
|
||||||
auto handle = state.ctx->registers.w2;
|
auto handle{state.ctx->registers.w2};
|
||||||
auto id1 = state.ctx->registers.x3;
|
auto id1{state.ctx->registers.x3};
|
||||||
|
|
||||||
u64 out{};
|
u64 out{};
|
||||||
|
|
||||||
constexpr auto totalPhysicalMemory = 0xF8000000; // ~4 GB of RAM
|
constexpr u64 totalPhysicalMemory{0xF8000000}; // ~4 GB of RAM
|
||||||
|
|
||||||
switch (id0) {
|
switch (id0) {
|
||||||
case constant::infoState::AllowedCpuIdBitmask:
|
case constant::infoState::AllowedCpuIdBitmask:
|
||||||
|
@ -8,34 +8,34 @@
|
|||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant::infoState {
|
namespace constant::infoState {
|
||||||
// 1.0.0+
|
// 1.0.0+
|
||||||
constexpr u8 AllowedCpuIdBitmask = 0x0;
|
constexpr u8 AllowedCpuIdBitmask{0x0};
|
||||||
constexpr u8 AllowedThreadPriorityMask = 0x1;
|
constexpr u8 AllowedThreadPriorityMask{0x1};
|
||||||
constexpr u8 AliasRegionBaseAddr = 0x2;
|
constexpr u8 AliasRegionBaseAddr{0x2};
|
||||||
constexpr u8 AliasRegionSize = 0x3;
|
constexpr u8 AliasRegionSize{0x3};
|
||||||
constexpr u8 HeapRegionBaseAddr = 0x4;
|
constexpr u8 HeapRegionBaseAddr{0x4};
|
||||||
constexpr u8 HeapRegionSize = 0x5;
|
constexpr u8 HeapRegionSize{0x5};
|
||||||
constexpr u8 TotalMemoryAvailable = 0x6;
|
constexpr u8 TotalMemoryAvailable{0x6};
|
||||||
constexpr u8 TotalMemoryUsage = 0x7;
|
constexpr u8 TotalMemoryUsage{0x7};
|
||||||
constexpr u8 IsCurrentProcessBeingDebugged = 0x8;
|
constexpr u8 IsCurrentProcessBeingDebugged{0x8};
|
||||||
constexpr u8 ResourceLimit = 0x9;
|
constexpr u8 ResourceLimit{0x9};
|
||||||
constexpr u8 IdleTickCount = 0xA;
|
constexpr u8 IdleTickCount{0xA};
|
||||||
constexpr u8 RandomEntropy = 0xB;
|
constexpr u8 RandomEntropy{0xB};
|
||||||
// 2.0.0+
|
// 2.0.0+
|
||||||
constexpr u8 AddressSpaceBaseAddr = 0xC;
|
constexpr u8 AddressSpaceBaseAddr{0xC};
|
||||||
constexpr u8 AddressSpaceSize = 0xD;
|
constexpr u8 AddressSpaceSize{0xD};
|
||||||
constexpr u8 StackRegionBaseAddr = 0xE;
|
constexpr u8 StackRegionBaseAddr{0xE};
|
||||||
constexpr u8 StackRegionSize = 0xF;
|
constexpr u8 StackRegionSize{0xF};
|
||||||
// 3.0.0+
|
// 3.0.0+
|
||||||
constexpr u8 PersonalMmHeapSize = 0x10;
|
constexpr u8 PersonalMmHeapSize{0x10};
|
||||||
constexpr u8 PersonalMmHeapUsage = 0x11;
|
constexpr u8 PersonalMmHeapUsage{0x11};
|
||||||
constexpr u8 TitleId = 0x12;
|
constexpr u8 TitleId{0x12};
|
||||||
// 4.0.0+
|
// 4.0.0+
|
||||||
constexpr u8 PrivilegedProcessId = 0x13;
|
constexpr u8 PrivilegedProcessId{0x13};
|
||||||
// 5.0.0+
|
// 5.0.0+
|
||||||
constexpr u8 UserExceptionContextAddr = 0x14;
|
constexpr u8 UserExceptionContextAddr{0x14};
|
||||||
// 6.0.0+
|
// 6.0.0+
|
||||||
constexpr u8 TotalMemoryAvailableWithoutMmHeap = 0x15;
|
constexpr u8 TotalMemoryAvailableWithoutMmHeap{0x15};
|
||||||
constexpr u8 TotalMemoryUsedWithoutMmHeap = 0x16;
|
constexpr u8 TotalMemoryUsedWithoutMmHeap{0x16};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace kernel::svc {
|
namespace kernel::svc {
|
||||||
|
@ -18,7 +18,7 @@ namespace skyline::kernel::type {
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
throw exception("An error occurred while creating shared memory: {}", fd);
|
throw exception("An error occurred while creating shared memory: {}", fd);
|
||||||
|
|
||||||
auto host = mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0);
|
auto host{mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0)};
|
||||||
if (host == MAP_FAILED)
|
if (host == MAP_FAILED)
|
||||||
throw exception("An occurred while mapping shared memory: {}", strerror(errno));
|
throw exception("An occurred while mapping shared memory: {}", strerror(errno));
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ namespace skyline::kernel::type {
|
|||||||
if (fregs.x0 < 0)
|
if (fregs.x0 < 0)
|
||||||
throw exception("An error occurred while remapping private memory in child process");
|
throw exception("An error occurred while remapping private memory in child process");
|
||||||
|
|
||||||
auto chunk = state.os->memory.GetChunk(address);
|
auto chunk{state.os->memory.GetChunk(address)};
|
||||||
state.process->WriteMemory(reinterpret_cast<void *>(chunk->host), address, std::min(nSize, size), true);
|
state.process->WriteMemory(reinterpret_cast<void *>(chunk->host), address, std::min(nSize, size), true);
|
||||||
|
|
||||||
for (const auto &block : chunk->blockList) {
|
for (const auto &block : chunk->blockList) {
|
||||||
@ -105,7 +105,7 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
munmap(reinterpret_cast<void *>(chunk->host), size);
|
munmap(reinterpret_cast<void *>(chunk->host), size);
|
||||||
|
|
||||||
auto host = mmap(reinterpret_cast<void *>(chunk->host), nSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0);
|
auto host{mmap(reinterpret_cast<void *>(chunk->host), nSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0)};
|
||||||
if (host == MAP_FAILED)
|
if (host == MAP_FAILED)
|
||||||
throw exception("An occurred while mapping shared memory: {}", strerror(errno));
|
throw exception("An occurred while mapping shared memory: {}", strerror(errno));
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ namespace skyline::kernel::type {
|
|||||||
if (fregs.x0 < 0)
|
if (fregs.x0 < 0)
|
||||||
throw exception("An error occurred while updating private memory's permissions in child process");
|
throw exception("An error occurred while updating private memory's permissions in child process");
|
||||||
|
|
||||||
auto chunk = state.os->memory.GetChunk(address);
|
auto chunk{state.os->memory.GetChunk(address)};
|
||||||
|
|
||||||
// If a static code region has been mapped as writable it needs to be changed to mutable
|
// If a static code region has been mapped as writable it needs to be changed to mutable
|
||||||
if (chunk->state.value == memory::states::CodeStatic.value && permission.w)
|
if (chunk->state.value == memory::states::CodeStatic.value && permission.w)
|
||||||
@ -153,7 +153,7 @@ namespace skyline::kernel::type {
|
|||||||
} catch (const std::exception &) {
|
} catch (const std::exception &) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto chunk = state.os->memory.GetChunk(address);
|
auto chunk{state.os->memory.GetChunk(address)};
|
||||||
if (chunk) {
|
if (chunk) {
|
||||||
munmap(reinterpret_cast<void *>(chunk->host), chunk->size);
|
munmap(reinterpret_cast<void *>(chunk->host), chunk->size);
|
||||||
state.os->memory.DeleteChunk(address);
|
state.os->memory.DeleteChunk(address);
|
||||||
|
@ -39,16 +39,16 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
u64 address;
|
u64 address;
|
||||||
if (tlsPages.empty()) {
|
if (tlsPages.empty()) {
|
||||||
auto region = state.os->memory.tlsIo;
|
auto region{state.os->memory.tlsIo};
|
||||||
address = region.size ? region.address : 0;
|
address = region.size ? region.address : 0;
|
||||||
} else {
|
} else {
|
||||||
address = (*(tlsPages.end() - 1))->address + PAGE_SIZE;
|
address = (*(tlsPages.end() - 1))->address + PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tlsMem = NewHandle<KPrivateMemory>(address, PAGE_SIZE, memory::Permission(true, true, false), memory::states::ThreadLocal).item;
|
auto tlsMem{NewHandle<KPrivateMemory>(address, PAGE_SIZE, memory::Permission(true, true, false), memory::states::ThreadLocal).item};
|
||||||
tlsPages.push_back(std::make_shared<TlsPage>(tlsMem->address));
|
tlsPages.push_back(std::make_shared<TlsPage>(tlsMem->address));
|
||||||
|
|
||||||
auto &tlsPage = tlsPages.back();
|
auto &tlsPage{tlsPages.back()};
|
||||||
if (tlsPages.empty())
|
if (tlsPages.empty())
|
||||||
tlsPage->ReserveSlot(); // User-mode exception handling
|
tlsPage->ReserveSlot(); // User-mode exception handling
|
||||||
|
|
||||||
@ -56,15 +56,15 @@ namespace skyline::kernel::type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void KProcess::InitializeMemory() {
|
void KProcess::InitializeMemory() {
|
||||||
constexpr size_t DefHeapSize = 0x200000; // The default amount of heap
|
constexpr size_t DefHeapSize{0x200000}; // The default amount of heap
|
||||||
heap = NewHandle<KPrivateMemory>(state.os->memory.heap.address, DefHeapSize, memory::Permission{true, true, false}, memory::states::Heap).item;
|
heap = NewHandle<KPrivateMemory>(state.os->memory.heap.address, DefHeapSize, memory::Permission{true, true, false}, memory::states::Heap).item;
|
||||||
threads[pid]->tls = GetTlsSlot();
|
threads[pid]->tls = GetTlsSlot();
|
||||||
}
|
}
|
||||||
|
|
||||||
KProcess::KProcess(const DeviceState &state, pid_t pid, u64 entryPoint, std::shared_ptr<type::KSharedMemory> &stack, std::shared_ptr<type::KSharedMemory> &tlsMemory) : pid(pid), stack(stack), KSyncObject(state, KType::KProcess) {
|
KProcess::KProcess(const DeviceState &state, pid_t pid, u64 entryPoint, std::shared_ptr<type::KSharedMemory> &stack, std::shared_ptr<type::KSharedMemory> &tlsMemory) : pid(pid), stack(stack), KSyncObject(state, KType::KProcess) {
|
||||||
constexpr auto DefaultPriority = 44; // The default priority of a process
|
constexpr u8 DefaultPriority{44}; // The default priority of a process
|
||||||
|
|
||||||
auto thread = NewHandle<KThread>(pid, entryPoint, 0x0, stack->guest.address + stack->guest.size, 0, DefaultPriority, this, tlsMemory).item;
|
auto thread{NewHandle<KThread>(pid, entryPoint, 0x0, stack->guest.address + stack->guest.size, 0, DefaultPriority, this, tlsMemory).item};
|
||||||
threads[pid] = thread;
|
threads[pid] = thread;
|
||||||
state.nce->WaitThreadInit(thread);
|
state.nce->WaitThreadInit(thread);
|
||||||
|
|
||||||
@ -79,8 +79,8 @@ namespace skyline::kernel::type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<KThread> KProcess::CreateThread(u64 entryPoint, u64 entryArg, u64 stackTop, i8 priority) {
|
std::shared_ptr<KThread> KProcess::CreateThread(u64 entryPoint, u64 entryArg, u64 stackTop, i8 priority) {
|
||||||
auto size = (sizeof(ThreadContext) + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
|
auto size{(sizeof(ThreadContext) + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1)};
|
||||||
auto tlsMem = std::make_shared<type::KSharedMemory>(state, 0, size, memory::Permission{true, true, false}, memory::states::Reserved);
|
auto tlsMem{std::make_shared<type::KSharedMemory>(state, 0, size, memory::Permission{true, true, false}, memory::states::Reserved)};
|
||||||
|
|
||||||
Registers fregs{
|
Registers fregs{
|
||||||
.x0 = CLONE_THREAD | CLONE_SIGHAND | CLONE_PTRACE | CLONE_FS | CLONE_VM | CLONE_FILES | CLONE_IO,
|
.x0 = CLONE_THREAD | CLONE_SIGHAND | CLONE_PTRACE | CLONE_FS | CLONE_VM | CLONE_FILES | CLONE_IO,
|
||||||
@ -95,21 +95,21 @@ namespace skyline::kernel::type {
|
|||||||
if (static_cast<int>(fregs.x0) < 0)
|
if (static_cast<int>(fregs.x0) < 0)
|
||||||
throw exception("Cannot create thread: Address: 0x{:X}, Stack Top: 0x{:X}", entryPoint, stackTop);
|
throw exception("Cannot create thread: Address: 0x{:X}, Stack Top: 0x{:X}", entryPoint, stackTop);
|
||||||
|
|
||||||
auto pid = static_cast<pid_t>(fregs.x0);
|
auto pid{static_cast<pid_t>(fregs.x0)};
|
||||||
auto process = NewHandle<KThread>(pid, entryPoint, entryArg, stackTop, GetTlsSlot(), priority, this, tlsMem).item;
|
auto process{NewHandle<KThread>(pid, entryPoint, entryArg, stackTop, GetTlsSlot(), priority, this, tlsMem).item};
|
||||||
threads[pid] = process;
|
threads[pid] = process;
|
||||||
|
|
||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 KProcess::GetHostAddress(u64 address) {
|
u64 KProcess::GetHostAddress(u64 address) {
|
||||||
auto chunk = state.os->memory.GetChunk(address);
|
auto chunk{state.os->memory.GetChunk(address)};
|
||||||
return (chunk && chunk->host) ? chunk->host + (address - chunk->address) : 0;
|
return (chunk && chunk->host) ? chunk->host + (address - chunk->address) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KProcess::ReadMemory(void *destination, u64 offset, size_t size, bool forceGuest) {
|
void KProcess::ReadMemory(void *destination, u64 offset, size_t size, bool forceGuest) {
|
||||||
if (!forceGuest) {
|
if (!forceGuest) {
|
||||||
auto source = GetHostAddress(offset);
|
auto source{GetHostAddress(offset)};
|
||||||
|
|
||||||
if (source) {
|
if (source) {
|
||||||
std::memcpy(destination, reinterpret_cast<void *>(source), size);
|
std::memcpy(destination, reinterpret_cast<void *>(source), size);
|
||||||
@ -133,7 +133,7 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
void KProcess::WriteMemory(const void *source, u64 offset, size_t size, bool forceGuest) {
|
void KProcess::WriteMemory(const void *source, u64 offset, size_t size, bool forceGuest) {
|
||||||
if (!forceGuest) {
|
if (!forceGuest) {
|
||||||
auto destination = GetHostAddress(offset);
|
auto destination{GetHostAddress(offset)};
|
||||||
|
|
||||||
if (destination) {
|
if (destination) {
|
||||||
std::memcpy(reinterpret_cast<void *>(destination), source, size);
|
std::memcpy(reinterpret_cast<void *>(destination), source, size);
|
||||||
@ -156,8 +156,8 @@ namespace skyline::kernel::type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void KProcess::CopyMemory(u64 source, u64 destination, size_t size) {
|
void KProcess::CopyMemory(u64 source, u64 destination, size_t size) {
|
||||||
auto sourceHost = GetHostAddress(source);
|
auto sourceHost{GetHostAddress(source)};
|
||||||
auto destinationHost = GetHostAddress(destination);
|
auto destinationHost{GetHostAddress(destination)};
|
||||||
|
|
||||||
if (sourceHost && destinationHost) {
|
if (sourceHost && destinationHost) {
|
||||||
std::memcpy(reinterpret_cast<void *>(destinationHost), reinterpret_cast<const void *>(sourceHost), size);
|
std::memcpy(reinterpret_cast<void *>(destinationHost), reinterpret_cast<const void *>(sourceHost), size);
|
||||||
@ -181,12 +181,12 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
std::optional<KProcess::HandleOut<KMemory>> KProcess::GetMemoryObject(u64 address) {
|
std::optional<KProcess::HandleOut<KMemory>> KProcess::GetMemoryObject(u64 address) {
|
||||||
for (KHandle index{}; index < handles.size(); index++) {
|
for (KHandle index{}; index < handles.size(); index++) {
|
||||||
auto& object = handles[index];
|
auto& object{handles[index]};
|
||||||
switch (object->objectType) {
|
switch (object->objectType) {
|
||||||
case type::KType::KPrivateMemory:
|
case type::KType::KPrivateMemory:
|
||||||
case type::KType::KSharedMemory:
|
case type::KType::KSharedMemory:
|
||||||
case type::KType::KTransferMemory: {
|
case type::KType::KTransferMemory: {
|
||||||
auto mem = std::static_pointer_cast<type::KMemory>(object);
|
auto mem{std::static_pointer_cast<type::KMemory>(object)};
|
||||||
if (mem->IsInside(address))
|
if (mem->IsInside(address))
|
||||||
return std::make_optional<KProcess::HandleOut<KMemory>>({mem, constant::BaseHandleIndex + index});
|
return std::make_optional<KProcess::HandleOut<KMemory>>({mem, constant::BaseHandleIndex + index});
|
||||||
}
|
}
|
||||||
@ -201,11 +201,11 @@ namespace skyline::kernel::type {
|
|||||||
bool KProcess::MutexLock(u64 address, KHandle owner) {
|
bool KProcess::MutexLock(u64 address, KHandle owner) {
|
||||||
std::unique_lock lock(mutexLock);
|
std::unique_lock lock(mutexLock);
|
||||||
|
|
||||||
auto mtx = GetPointer<u32>(address);
|
auto mtx{GetPointer<u32>(address)};
|
||||||
auto &mtxWaiters = mutexes[address];
|
auto &mtxWaiters{mutexes[address]};
|
||||||
|
|
||||||
if (mtxWaiters.empty()) {
|
if (mtxWaiters.empty()) {
|
||||||
u32 mtxExpected = 0;
|
u32 mtxExpected{};
|
||||||
if (__atomic_compare_exchange_n(mtx, &mtxExpected, (constant::MtxOwnerMask & state.thread->handle), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
|
if (__atomic_compare_exchange_n(mtx, &mtxExpected, (constant::MtxOwnerMask & state.thread->handle), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -214,7 +214,7 @@ namespace skyline::kernel::type {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::shared_ptr<WaitStatus> status;
|
std::shared_ptr<WaitStatus> status;
|
||||||
for (auto it = mtxWaiters.begin();; it++) {
|
for (auto it{mtxWaiters.begin()};; it++) {
|
||||||
if (it != mtxWaiters.end() && (*it)->priority >= state.thread->priority)
|
if (it != mtxWaiters.end() && (*it)->priority >= state.thread->priority)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ namespace skyline::kernel::type {
|
|||||||
lock.lock();
|
lock.lock();
|
||||||
status->flag = false;
|
status->flag = false;
|
||||||
|
|
||||||
for (auto it = mtxWaiters.begin(); it != mtxWaiters.end(); it++) {
|
for (auto it{mtxWaiters.begin()}; it != mtxWaiters.end(); it++) {
|
||||||
if ((*it)->handle == state.thread->handle) {
|
if ((*it)->handle == state.thread->handle) {
|
||||||
mtxWaiters.erase(it);
|
mtxWaiters.erase(it);
|
||||||
break;
|
break;
|
||||||
@ -241,13 +241,13 @@ namespace skyline::kernel::type {
|
|||||||
bool KProcess::MutexUnlock(u64 address) {
|
bool KProcess::MutexUnlock(u64 address) {
|
||||||
std::unique_lock lock(mutexLock);
|
std::unique_lock lock(mutexLock);
|
||||||
|
|
||||||
auto mtx = GetPointer<u32>(address);
|
auto mtx{GetPointer<u32>(address)};
|
||||||
auto &mtxWaiters = mutexes[address];
|
auto &mtxWaiters{mutexes[address]};
|
||||||
u32 mtxDesired{};
|
u32 mtxDesired{};
|
||||||
if (!mtxWaiters.empty())
|
if (!mtxWaiters.empty())
|
||||||
mtxDesired = (*mtxWaiters.begin())->handle | ((mtxWaiters.size() > 1) ? ~constant::MtxOwnerMask : 0);
|
mtxDesired = (*mtxWaiters.begin())->handle | ((mtxWaiters.size() > 1) ? ~constant::MtxOwnerMask : 0);
|
||||||
|
|
||||||
u32 mtxExpected = (constant::MtxOwnerMask & state.thread->handle) | ~constant::MtxOwnerMask;
|
u32 mtxExpected{(constant::MtxOwnerMask & state.thread->handle) | ~constant::MtxOwnerMask};
|
||||||
if (!__atomic_compare_exchange_n(mtx, &mtxExpected, mtxDesired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
|
if (!__atomic_compare_exchange_n(mtx, &mtxExpected, mtxDesired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
|
||||||
mtxExpected &= constant::MtxOwnerMask;
|
mtxExpected &= constant::MtxOwnerMask;
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ namespace skyline::kernel::type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mtxDesired) {
|
if (mtxDesired) {
|
||||||
auto status = (*mtxWaiters.begin());
|
auto status{(*mtxWaiters.begin())};
|
||||||
status->flag = true;
|
status->flag = true;
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
while (status->flag);
|
while (status->flag);
|
||||||
@ -268,10 +268,10 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
bool KProcess::ConditionalVariableWait(u64 conditionalAddress, u64 mutexAddress, u64 timeout) {
|
bool KProcess::ConditionalVariableWait(u64 conditionalAddress, u64 mutexAddress, u64 timeout) {
|
||||||
std::unique_lock lock(conditionalLock);
|
std::unique_lock lock(conditionalLock);
|
||||||
auto &condWaiters = conditionals[conditionalAddress];
|
auto &condWaiters{conditionals[conditionalAddress]};
|
||||||
|
|
||||||
std::shared_ptr<WaitStatus> status;
|
std::shared_ptr<WaitStatus> status;
|
||||||
for (auto it = condWaiters.begin();; it++) {
|
for (auto it{condWaiters.begin()};; it++) {
|
||||||
if (it != condWaiters.end() && (*it)->priority >= state.thread->priority)
|
if (it != condWaiters.end() && (*it)->priority >= state.thread->priority)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ namespace skyline::kernel::type {
|
|||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
bool timedOut{};
|
bool timedOut{};
|
||||||
auto start = util::GetTimeNs();
|
auto start{util::GetTimeNs()};
|
||||||
while (!status->flag)
|
while (!status->flag)
|
||||||
if ((util::GetTimeNs() - start) >= timeout)
|
if ((util::GetTimeNs() - start) >= timeout)
|
||||||
timedOut = true;
|
timedOut = true;
|
||||||
@ -295,7 +295,7 @@ namespace skyline::kernel::type {
|
|||||||
else
|
else
|
||||||
status->flag = false;
|
status->flag = false;
|
||||||
|
|
||||||
for (auto it = condWaiters.begin(); it != condWaiters.end(); it++) {
|
for (auto it{condWaiters.begin()}; it != condWaiters.end(); it++) {
|
||||||
if ((*it)->handle == state.thread->handle) {
|
if ((*it)->handle == state.thread->handle) {
|
||||||
condWaiters.erase(it);
|
condWaiters.erase(it);
|
||||||
break;
|
break;
|
||||||
@ -310,14 +310,14 @@ namespace skyline::kernel::type {
|
|||||||
void KProcess::ConditionalVariableSignal(u64 address, u64 amount) {
|
void KProcess::ConditionalVariableSignal(u64 address, u64 amount) {
|
||||||
std::unique_lock condLock(conditionalLock);
|
std::unique_lock condLock(conditionalLock);
|
||||||
|
|
||||||
auto &condWaiters = conditionals[address];
|
auto &condWaiters{conditionals[address]};
|
||||||
u64 count{};
|
u64 count{};
|
||||||
|
|
||||||
auto iter = condWaiters.begin();
|
auto iter{condWaiters.begin()};
|
||||||
while (iter != condWaiters.end() && count < amount) {
|
while (iter != condWaiters.end() && count < amount) {
|
||||||
auto &thread = *iter;
|
auto &thread{*iter};
|
||||||
auto mtx = GetPointer<u32>(thread->mutexAddress);
|
auto mtx{GetPointer<u32>(thread->mutexAddress)};
|
||||||
u32 mtxValue = __atomic_load_n(mtx, __ATOMIC_SEQ_CST);
|
u32 mtxValue{__atomic_load_n(mtx, __ATOMIC_SEQ_CST)};
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
u32 mtxDesired{};
|
u32 mtxDesired{};
|
||||||
@ -337,10 +337,10 @@ namespace skyline::kernel::type {
|
|||||||
if (mtxValue && ((mtxValue & constant::MtxOwnerMask) != state.thread->handle)) {
|
if (mtxValue && ((mtxValue & constant::MtxOwnerMask) != state.thread->handle)) {
|
||||||
std::unique_lock mtxLock(mutexLock);
|
std::unique_lock mtxLock(mutexLock);
|
||||||
|
|
||||||
auto &mtxWaiters = mutexes[thread->mutexAddress];
|
auto &mtxWaiters{mutexes[thread->mutexAddress]};
|
||||||
std::shared_ptr<WaitStatus> status;
|
std::shared_ptr<WaitStatus> status;
|
||||||
|
|
||||||
for (auto it = mtxWaiters.begin();; it++) {
|
for (auto it{mtxWaiters.begin()};; it++) {
|
||||||
if (it != mtxWaiters.end() && (*it)->priority >= thread->priority)
|
if (it != mtxWaiters.end() && (*it)->priority >= thread->priority)
|
||||||
continue;
|
continue;
|
||||||
status = std::make_shared<WaitStatus>(thread->priority, thread->handle);
|
status = std::make_shared<WaitStatus>(thread->priority, thread->handle);
|
||||||
@ -353,7 +353,7 @@ namespace skyline::kernel::type {
|
|||||||
mtxLock.lock();
|
mtxLock.lock();
|
||||||
status->flag = false;
|
status->flag = false;
|
||||||
|
|
||||||
for (auto it = mtxWaiters.begin(); it != mtxWaiters.end(); it++) {
|
for (auto it{mtxWaiters.begin()}; it != mtxWaiters.end(); it++) {
|
||||||
if ((*it)->handle == thread->handle) {
|
if ((*it)->handle == thread->handle) {
|
||||||
mtxWaiters.erase(it);
|
mtxWaiters.erase(it);
|
||||||
break;
|
break;
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr auto TlsSlotSize = 0x200; //!< The size of a single TLS slot
|
constexpr u16 TlsSlotSize{0x200}; //!< The size of a single TLS slot
|
||||||
constexpr auto TlsSlots = PAGE_SIZE / TlsSlotSize; //!< The amount of TLS slots in a single page
|
constexpr u8 TlsSlots{PAGE_SIZE / TlsSlotSize}; //!< The amount of TLS slots in a single page
|
||||||
constexpr KHandle BaseHandleIndex = 0xD000; // The index of the base handle
|
constexpr KHandle BaseHandleIndex{0xD000}; // The index of the base handle
|
||||||
constexpr u32 MtxOwnerMask = 0xBFFFFFFF; //!< The mask of values which contain the owner of a mutex
|
constexpr u32 MtxOwnerMask{0xBFFFFFFF}; //!< The mask of values which contain the owner of a mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace kernel::type {
|
namespace kernel::type {
|
||||||
@ -24,7 +24,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
class KProcess : public KSyncObject {
|
class KProcess : public KSyncObject {
|
||||||
private:
|
private:
|
||||||
KHandle handleIndex = constant::BaseHandleIndex; //!< This is used to keep track of what to map as an handle
|
KHandle handleIndex{constant::BaseHandleIndex}; //!< This is used to keep track of what to map as an handle
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class holds a single TLS page's status
|
* @brief This class holds a single TLS page's status
|
||||||
@ -35,8 +35,8 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
struct TlsPage {
|
struct TlsPage {
|
||||||
u64 address; //!< The address of the page allocated for TLS
|
u64 address; //!< The address of the page allocated for TLS
|
||||||
u8 index = 0; //!< The slots are assigned sequentially, this holds the index of the last TLS slot reserved
|
u8 index{}; //!< The slots are assigned sequentially, this holds the index of the last TLS slot reserved
|
||||||
bool slot[constant::TlsSlots]{0}; //!< An array of booleans denoting which TLS slots are reserved
|
bool slot[constant::TlsSlots]{}; //!< An array of booleans denoting which TLS slots are reserved
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param address The address of the allocated page
|
* @param address The address of the allocated page
|
||||||
@ -173,7 +173,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
inline Type &GetReference(u64 address) {
|
inline Type &GetReference(u64 address) {
|
||||||
auto source = GetPointer<Type>(address);
|
auto source{GetPointer<Type>(address)};
|
||||||
if (source)
|
if (source)
|
||||||
return *source;
|
return *source;
|
||||||
else
|
else
|
||||||
@ -188,7 +188,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
inline Type GetObject(u64 address) {
|
inline Type GetObject(u64 address) {
|
||||||
auto source = GetPointer<Type>(address);
|
auto source{GetPointer<Type>(address)};
|
||||||
if (source) {
|
if (source) {
|
||||||
return *source;
|
return *source;
|
||||||
} else {
|
} else {
|
||||||
@ -205,7 +205,7 @@ namespace skyline {
|
|||||||
* @return A copy of a string in guest memory
|
* @return A copy of a string in guest memory
|
||||||
*/
|
*/
|
||||||
inline std::string GetString(u64 address, size_t maxSize) {
|
inline std::string GetString(u64 address, size_t maxSize) {
|
||||||
auto source = GetPointer<char>(address);
|
auto source{GetPointer<char>(address)};
|
||||||
if (source)
|
if (source)
|
||||||
return std::string(source, maxSize);
|
return std::string(source, maxSize);
|
||||||
std::string debug(maxSize, '\0');
|
std::string debug(maxSize, '\0');
|
||||||
@ -221,7 +221,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
inline void WriteMemory(Type &item, u64 address) {
|
inline void WriteMemory(Type &item, u64 address) {
|
||||||
auto destination = GetPointer<Type>(address);
|
auto destination{GetPointer<Type>(address)};
|
||||||
if (destination) {
|
if (destination) {
|
||||||
*destination = item;
|
*destination = item;
|
||||||
} else {
|
} else {
|
||||||
@ -237,7 +237,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
inline void WriteMemory(const Type &item, u64 address) {
|
inline void WriteMemory(const Type &item, u64 address) {
|
||||||
auto destination = GetPointer<Type>(address);
|
auto destination{GetPointer<Type>(address)};
|
||||||
if (destination) {
|
if (destination) {
|
||||||
*destination = item;
|
*destination = item;
|
||||||
} else {
|
} else {
|
||||||
@ -325,7 +325,7 @@ namespace skyline {
|
|||||||
else
|
else
|
||||||
throw exception("KProcess::GetHandle couldn't determine object type");
|
throw exception("KProcess::GetHandle couldn't determine object type");
|
||||||
try {
|
try {
|
||||||
auto& item = handles.at(handle - constant::BaseHandleIndex);
|
auto& item{handles.at(handle - constant::BaseHandleIndex)};
|
||||||
if (item != nullptr && item->objectType == objectType)
|
if (item != nullptr && item->objectType == objectType)
|
||||||
return std::static_pointer_cast<objectClass>(item);
|
return std::static_pointer_cast<objectClass>(item);
|
||||||
else if (item == nullptr)
|
else if (item == nullptr)
|
||||||
|
@ -115,7 +115,7 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
state.process->WriteMemory(reinterpret_cast<void *>(kernel.address), guest.address, std::min(guest.size, size), true);
|
state.process->WriteMemory(reinterpret_cast<void *>(kernel.address), guest.address, std::min(guest.size, size), true);
|
||||||
|
|
||||||
auto chunk = state.os->memory.GetChunk(guest.address);
|
auto chunk{state.os->memory.GetChunk(guest.address)};
|
||||||
for (const auto &block : chunk->blockList) {
|
for (const auto &block : chunk->blockList) {
|
||||||
if ((block.address - chunk->address) < guest.size) {
|
if ((block.address - chunk->address) < guest.size) {
|
||||||
fregs = {
|
fregs = {
|
||||||
@ -135,7 +135,7 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
munmap(reinterpret_cast<void *>(kernel.address), kernel.size);
|
munmap(reinterpret_cast<void *>(kernel.address), kernel.size);
|
||||||
|
|
||||||
auto host = mmap(reinterpret_cast<void *>(chunk->host), size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0);
|
auto host{mmap(reinterpret_cast<void *>(chunk->host), size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0)};
|
||||||
if (host == MAP_FAILED)
|
if (host == MAP_FAILED)
|
||||||
throw exception("An occurred while mapping shared memory: {}", strerror(errno));
|
throw exception("An occurred while mapping shared memory: {}", strerror(errno));
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
munmap(reinterpret_cast<void *>(kernel.address), kernel.size);
|
munmap(reinterpret_cast<void *>(kernel.address), kernel.size);
|
||||||
|
|
||||||
auto address = mmap(reinterpret_cast<void *>(kernel.address), size, kernel.permission.Get(), MAP_SHARED, fd, 0);
|
auto address{mmap(reinterpret_cast<void *>(kernel.address), size, kernel.permission.Get(), MAP_SHARED, fd, 0)};
|
||||||
if (address == MAP_FAILED)
|
if (address == MAP_FAILED)
|
||||||
throw exception("An occurred while mapping shared memory: {}", strerror(errno));
|
throw exception("An occurred while mapping shared memory: {}", strerror(errno));
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ namespace skyline::kernel::type {
|
|||||||
if (fregs.x0 < 0)
|
if (fregs.x0 < 0)
|
||||||
throw exception("An error occurred while updating shared memory's permissions in guest");
|
throw exception("An error occurred while updating shared memory's permissions in guest");
|
||||||
|
|
||||||
auto chunk = state.os->memory.GetChunk(address);
|
auto chunk{state.os->memory.GetChunk(address)};
|
||||||
BlockDescriptor block{
|
BlockDescriptor block{
|
||||||
.address = address,
|
.address = address,
|
||||||
.size = size,
|
.size = size,
|
||||||
|
@ -37,7 +37,7 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
void KThread::UpdatePriority(i8 priority) {
|
void KThread::UpdatePriority(i8 priority) {
|
||||||
this->priority = priority;
|
this->priority = priority;
|
||||||
auto priorityValue = androidPriority.Rescale(switchPriority, priority);
|
auto priorityValue{androidPriority.Rescale(switchPriority, priority)};
|
||||||
|
|
||||||
if (setpriority(PRIO_PROCESS, static_cast<id_t>(tid), priorityValue) == -1)
|
if (setpriority(PRIO_PROCESS, static_cast<id_t>(tid), priorityValue) == -1)
|
||||||
throw exception("Couldn't set process priority to {} for PID: {}", priorityValue, tid);
|
throw exception("Couldn't set process priority to {} for PID: {}", priorityValue, tid);
|
||||||
|
@ -58,7 +58,7 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
nSize = nSize ? nSize : size;
|
nSize = nSize ? nSize : size;
|
||||||
|
|
||||||
ChunkDescriptor chunk = host ? hostChunk : *state.os->memory.GetChunk(address);
|
ChunkDescriptor chunk{host ? hostChunk : *state.os->memory.GetChunk(address)};
|
||||||
chunk.address = nAddress;
|
chunk.address = nAddress;
|
||||||
chunk.size = nSize;
|
chunk.size = nSize;
|
||||||
MemoryManager::ResizeChunk(&chunk, nSize);
|
MemoryManager::ResizeChunk(&chunk, nSize);
|
||||||
@ -167,7 +167,7 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
size = nSize;
|
size = nSize;
|
||||||
|
|
||||||
auto chunk = state.os->memory.GetChunk(address);
|
auto chunk{state.os->memory.GetChunk(address)};
|
||||||
MemoryManager::ResizeChunk(chunk, size);
|
MemoryManager::ResizeChunk(chunk, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,7 +196,7 @@ namespace skyline::kernel::type {
|
|||||||
if (fregs.x0 < 0)
|
if (fregs.x0 < 0)
|
||||||
throw exception("An error occurred while updating transfer memory's permissions in guest");
|
throw exception("An error occurred while updating transfer memory's permissions in guest");
|
||||||
|
|
||||||
auto chunk = state.os->memory.GetChunk(address);
|
auto chunk{state.os->memory.GetChunk(address)};
|
||||||
MemoryManager::InsertBlock(chunk, block);
|
MemoryManager::InsertBlock(chunk, block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
|
|
||||||
namespace skyline::loader {
|
namespace skyline::loader {
|
||||||
Loader::ExecutableLoadInfo Loader::LoadExecutable(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state, Executable &executable, size_t offset) {
|
Loader::ExecutableLoadInfo Loader::LoadExecutable(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state, Executable &executable, size_t offset) {
|
||||||
u64 base = constant::BaseAddress + offset;
|
u64 base{constant::BaseAddress + offset};
|
||||||
|
|
||||||
u64 textSize = executable.text.contents.size();
|
u64 textSize{executable.text.contents.size()};
|
||||||
u64 roSize = executable.ro.contents.size();
|
u64 roSize{executable.ro.contents.size()};
|
||||||
u64 dataSize = executable.data.contents.size() + executable.bssSize;
|
u64 dataSize{executable.data.contents.size() + executable.bssSize};
|
||||||
|
|
||||||
if (!util::PageAligned(textSize) || !util::PageAligned(roSize) || !util::PageAligned(dataSize))
|
if (!util::PageAligned(textSize) || !util::PageAligned(roSize) || !util::PageAligned(dataSize))
|
||||||
throw exception("LoadProcessData: Sections are not aligned with page size: 0x{:X}, 0x{:X}, 0x{:X}", textSize, roSize, dataSize);
|
throw exception("LoadProcessData: Sections are not aligned with page size: 0x{:X}, 0x{:X}, 0x{:X}", textSize, roSize, dataSize);
|
||||||
@ -21,11 +21,11 @@ namespace skyline::loader {
|
|||||||
throw exception("LoadProcessData: Section offsets are not aligned with page size: 0x{:X}, 0x{:X}, 0x{:X}", executable.text.offset, executable.ro.offset, executable.data.offset);
|
throw exception("LoadProcessData: Section offsets are not aligned with page size: 0x{:X}, 0x{:X}, 0x{:X}", executable.text.offset, executable.ro.offset, executable.data.offset);
|
||||||
|
|
||||||
// The data section will always be the last section in memory, so put the patch section after it
|
// The data section will always be the last section in memory, so put the patch section after it
|
||||||
u64 patchOffset = executable.data.offset + dataSize;
|
u64 patchOffset{executable.data.offset + dataSize};
|
||||||
std::vector<u32> patch = state.nce->PatchCode(executable.text.contents, base, patchOffset);
|
std::vector<u32> patch = state.nce->PatchCode(executable.text.contents, base, patchOffset);
|
||||||
|
|
||||||
u64 patchSize = patch.size() * sizeof(u32);
|
u64 patchSize{patch.size() * sizeof(u32)};
|
||||||
u64 padding = util::AlignUp(patchSize, PAGE_SIZE) - patchSize;
|
u64 padding{util::AlignUp(patchSize, PAGE_SIZE) - patchSize};
|
||||||
|
|
||||||
process->NewHandle<kernel::type::KPrivateMemory>(base + executable.text.offset, textSize, memory::Permission{true, false, true}, memory::states::CodeStatic); // R-X
|
process->NewHandle<kernel::type::KPrivateMemory>(base + executable.text.offset, textSize, memory::Permission{true, false, true}, memory::states::CodeStatic); // R-X
|
||||||
state.logger->Debug("Successfully mapped section .text @ 0x{0:X}, Size = 0x{1:X}", base + executable.text.offset, textSize);
|
state.logger->Debug("Successfully mapped section .text @ 0x{0:X}, Size = 0x{1:X}", base + executable.text.offset, textSize);
|
||||||
|
@ -17,13 +17,13 @@ namespace skyline::loader {
|
|||||||
if (exeFs == nullptr)
|
if (exeFs == nullptr)
|
||||||
throw exception("Cannot load a null ExeFS");
|
throw exception("Cannot load a null ExeFS");
|
||||||
|
|
||||||
auto nsoFile = exeFs->OpenFile("rtld");
|
auto nsoFile{exeFs->OpenFile("rtld")};
|
||||||
if (nsoFile == nullptr)
|
if (nsoFile == nullptr)
|
||||||
throw exception("Cannot load an ExeFS that doesn't contain rtld");
|
throw exception("Cannot load an ExeFS that doesn't contain rtld");
|
||||||
|
|
||||||
auto loadInfo = NsoLoader::LoadNso(nsoFile, process, state);
|
auto loadInfo{NsoLoader::LoadNso(nsoFile, process, state)};
|
||||||
u64 offset = loadInfo.size;
|
u64 offset{loadInfo.size};
|
||||||
u64 base = loadInfo.base;
|
u64 base{loadInfo.base};
|
||||||
|
|
||||||
state.logger->Info("Loaded nso 'rtld' at 0x{:X}", base);
|
state.logger->Info("Loaded nso 'rtld' at 0x{:X}", base);
|
||||||
|
|
||||||
|
@ -22,16 +22,16 @@ namespace skyline::loader {
|
|||||||
if (assetHeader.magic != util::MakeMagic<u32>("ASET"))
|
if (assetHeader.magic != util::MakeMagic<u32>("ASET"))
|
||||||
throw exception("Invalid ASET magic! 0x{0:X}", assetHeader.magic);
|
throw exception("Invalid ASET magic! 0x{0:X}", assetHeader.magic);
|
||||||
|
|
||||||
NroAssetSection &nacpHeader = assetHeader.nacp;
|
NroAssetSection &nacpHeader{assetHeader.nacp};
|
||||||
nacp = std::make_shared<vfs::NACP>(std::make_shared<vfs::RegionBacking>(backing, header.size + nacpHeader.offset, nacpHeader.size));
|
nacp = std::make_shared<vfs::NACP>(std::make_shared<vfs::RegionBacking>(backing, header.size + nacpHeader.offset, nacpHeader.size));
|
||||||
|
|
||||||
NroAssetSection &romFsHeader = assetHeader.romFs;
|
NroAssetSection &romFsHeader{assetHeader.romFs};
|
||||||
romFs = std::make_shared<vfs::RegionBacking>(backing, header.size + romFsHeader.offset, romFsHeader.size);
|
romFs = std::make_shared<vfs::RegionBacking>(backing, header.size + romFsHeader.offset, romFsHeader.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> NroLoader::GetIcon() {
|
std::vector<u8> NroLoader::GetIcon() {
|
||||||
NroAssetSection &segmentHeader = assetHeader.icon;
|
NroAssetSection &segmentHeader{assetHeader.icon};
|
||||||
std::vector<u8> buffer(segmentHeader.size);
|
std::vector<u8> buffer(segmentHeader.size);
|
||||||
|
|
||||||
backing->Read(buffer.data(), header.size + segmentHeader.offset, segmentHeader.size);
|
backing->Read(buffer.data(), header.size + segmentHeader.offset, segmentHeader.size);
|
||||||
@ -59,7 +59,7 @@ namespace skyline::loader {
|
|||||||
|
|
||||||
nroExecutable.bssSize = header.bssSize;
|
nroExecutable.bssSize = header.bssSize;
|
||||||
|
|
||||||
auto loadInfo = LoadExecutable(process, state, nroExecutable);
|
auto loadInfo{LoadExecutable(process, state, nroExecutable)};
|
||||||
state.os->memory.InitializeRegions(loadInfo.base, loadInfo.size, memory::AddressSpaceType::AddressSpace39Bit);
|
state.os->memory.InitializeRegions(loadInfo.base, loadInfo.size, memory::AddressSpaceType::AddressSpace39Bit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ namespace skyline::loader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NsoLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
void NsoLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||||
auto loadInfo = LoadNso(backing, process, state);
|
auto loadInfo{LoadNso(backing, process, state)};
|
||||||
|
|
||||||
state.os->memory.InitializeRegions(loadInfo.base, loadInfo.size, memory::AddressSpaceType::AddressSpace39Bit);
|
state.os->memory.InitializeRegions(loadInfo.base, loadInfo.size, memory::AddressSpaceType::AddressSpace39Bit);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ namespace skyline {
|
|||||||
if (__predict_false(!Surface))
|
if (__predict_false(!Surface))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto svc = state.ctx->svc;
|
auto svc{state.ctx->svc};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (kernel::svc::SvcTable[svc]) {
|
if (kernel::svc::SvcTable[svc]) {
|
||||||
@ -117,7 +117,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
void ExecuteFunctionCtx(ThreadCall call, Registers &funcRegs, ThreadContext *ctx) __attribute__ ((optnone)) {
|
void ExecuteFunctionCtx(ThreadCall call, Registers &funcRegs, ThreadContext *ctx) __attribute__ ((optnone)) {
|
||||||
ctx->threadCall = call;
|
ctx->threadCall = call;
|
||||||
Registers registers = ctx->registers;
|
Registers registers{ctx->registers};
|
||||||
|
|
||||||
while (ctx->state != ThreadState::WaitInit && ctx->state != ThreadState::WaitKernel);
|
while (ctx->state != ThreadState::WaitInit && ctx->state != ThreadState::WaitKernel);
|
||||||
|
|
||||||
@ -138,17 +138,17 @@ namespace skyline {
|
|||||||
if (state.process->status == kernel::type::KProcess::Status::Exiting)
|
if (state.process->status == kernel::type::KProcess::Status::Exiting)
|
||||||
throw exception("Executing function on Exiting process");
|
throw exception("Executing function on Exiting process");
|
||||||
|
|
||||||
auto thread = state.thread ? state.thread : state.process->threads.at(state.process->pid);
|
auto thread{state.thread ? state.thread : state.process->threads.at(state.process->pid)};
|
||||||
ExecuteFunctionCtx(call, funcRegs, reinterpret_cast<ThreadContext *>(thread->ctxMemory->kernel.address));
|
ExecuteFunctionCtx(call, funcRegs, reinterpret_cast<ThreadContext *>(thread->ctxMemory->kernel.address));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NCE::WaitThreadInit(std::shared_ptr<kernel::type::KThread> &thread) __attribute__ ((optnone)) {
|
void NCE::WaitThreadInit(std::shared_ptr<kernel::type::KThread> &thread) __attribute__ ((optnone)) {
|
||||||
auto ctx = reinterpret_cast<ThreadContext *>(thread->ctxMemory->kernel.address);
|
auto ctx{reinterpret_cast<ThreadContext *>(thread->ctxMemory->kernel.address)};
|
||||||
while (ctx->state == ThreadState::NotReady);
|
while (ctx->state == ThreadState::NotReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NCE::StartThread(u64 entryArg, u32 handle, std::shared_ptr<kernel::type::KThread> &thread) {
|
void NCE::StartThread(u64 entryArg, u32 handle, std::shared_ptr<kernel::type::KThread> &thread) {
|
||||||
auto ctx = reinterpret_cast<ThreadContext *>(thread->ctxMemory->kernel.address);
|
auto ctx{reinterpret_cast<ThreadContext *>(thread->ctxMemory->kernel.address)};
|
||||||
while (ctx->state != ThreadState::WaitInit);
|
while (ctx->state != ThreadState::WaitInit);
|
||||||
|
|
||||||
ctx->tpidrroEl0 = thread->tls;
|
ctx->tpidrroEl0 = thread->tls;
|
||||||
@ -169,8 +169,8 @@ namespace skyline {
|
|||||||
|
|
||||||
if (numHist) {
|
if (numHist) {
|
||||||
std::vector<u32> instrs(numHist);
|
std::vector<u32> instrs(numHist);
|
||||||
u64 size = sizeof(u32) * numHist;
|
u64 size{sizeof(u32) * numHist};
|
||||||
u64 offset = ctx->pc - size + (2 * sizeof(u32));
|
u64 offset{ctx->pc - size + (2 * sizeof(u32))};
|
||||||
|
|
||||||
state.process->ReadMemory(instrs.data(), offset, size);
|
state.process->ReadMemory(instrs.data(), offset, size);
|
||||||
|
|
||||||
@ -193,10 +193,10 @@ namespace skyline {
|
|||||||
if (ctx->sp)
|
if (ctx->sp)
|
||||||
regStr += fmt::format("\nStack Pointer: 0x{:X}", ctx->sp);
|
regStr += fmt::format("\nStack Pointer: 0x{:X}", ctx->sp);
|
||||||
|
|
||||||
constexpr u8 numRegisters = 31; //!< The amount of general-purpose registers in ARMv8
|
constexpr u8 numRegisters{31}; //!< The amount of general-purpose registers in ARMv8
|
||||||
|
|
||||||
for (u8 index = 0; index < numRegisters - 2; index += 2) {
|
for (u8 index{}; index < numRegisters - 2; index += 2) {
|
||||||
auto xStr = index < 10 ? " X" : "X";
|
auto xStr{index < 10 ? " X" : "X"};
|
||||||
regStr += fmt::format("\n{}{}: 0x{:<16X} {}{}: 0x{:X}", xStr, index, ctx->registers.regs[index], xStr, index + 1, ctx->registers.regs[index + 1]);
|
regStr += fmt::format("\n{}{}: 0x{:<16X} {}{}: 0x{:X}", xStr, index, ctx->registers.regs[index], xStr, index + 1, ctx->registers.regs[index + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,16 +210,16 @@ namespace skyline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u32> NCE::PatchCode(std::vector<u8> &code, u64 baseAddress, i64 offset) {
|
std::vector<u32> NCE::PatchCode(std::vector<u8> &code, u64 baseAddress, i64 offset) {
|
||||||
constexpr u32 TpidrEl0 = 0x5E82; // ID of TPIDR_EL0 in MRS
|
constexpr u32 TpidrEl0{0x5E82}; // ID of TPIDR_EL0 in MRS
|
||||||
constexpr u32 TpidrroEl0 = 0x5E83; // ID of TPIDRRO_EL0 in MRS
|
constexpr u32 TpidrroEl0{0x5E83}; // ID of TPIDRRO_EL0 in MRS
|
||||||
constexpr u32 CntfrqEl0 = 0x5F00; // ID of CNTFRQ_EL0 in MRS
|
constexpr u32 CntfrqEl0{0x5F00}; // ID of CNTFRQ_EL0 in MRS
|
||||||
constexpr u32 CntpctEl0 = 0x5F01; // ID of CNTPCT_EL0 in MRS
|
constexpr u32 CntpctEl0{0x5F01}; // ID of CNTPCT_EL0 in MRS
|
||||||
constexpr u32 CntvctEl0 = 0x5F02; // ID of CNTVCT_EL0 in MRS
|
constexpr u32 CntvctEl0{0x5F02}; // ID of CNTVCT_EL0 in MRS
|
||||||
constexpr u32 TegraX1Freq = 19200000; // The clock frequency of the Tegra X1 (19.2 MHz)
|
constexpr u32 TegraX1Freq{19200000}; // The clock frequency of the Tegra X1 (19.2 MHz)
|
||||||
|
|
||||||
u32 *start = reinterpret_cast<u32 *>(code.data());
|
u32 *start{reinterpret_cast<u32 *>(code.data())};
|
||||||
u32 *end = start + (code.size() / sizeof(u32));
|
u32 *end{start + (code.size() / sizeof(u32))};
|
||||||
i64 patchOffset = offset;
|
i64 patchOffset{offset};
|
||||||
|
|
||||||
std::vector<u32> patch((guest::SaveCtxSize + guest::LoadCtxSize + guest::SvcHandlerSize) / sizeof(u32));
|
std::vector<u32> patch((guest::SaveCtxSize + guest::LoadCtxSize + guest::SvcHandlerSize) / sizeof(u32));
|
||||||
|
|
||||||
@ -236,22 +236,22 @@ namespace skyline {
|
|||||||
if (!frequency)
|
if (!frequency)
|
||||||
asm("MRS %0, CNTFRQ_EL0" : "=r"(frequency));
|
asm("MRS %0, CNTFRQ_EL0" : "=r"(frequency));
|
||||||
|
|
||||||
for (u32 *address = start; address < end; address++) {
|
for (u32 *address{start}; address < end; address++) {
|
||||||
auto instrSvc = reinterpret_cast<instr::Svc *>(address);
|
auto instrSvc{reinterpret_cast<instr::Svc *>(address)};
|
||||||
auto instrMrs = reinterpret_cast<instr::Mrs *>(address);
|
auto instrMrs{reinterpret_cast<instr::Mrs *>(address)};
|
||||||
auto instrMsr = reinterpret_cast<instr::Msr *>(address);
|
auto instrMsr{reinterpret_cast<instr::Msr *>(address)};
|
||||||
|
|
||||||
if (instrSvc->Verify()) {
|
if (instrSvc->Verify()) {
|
||||||
// If this is an SVC we need to branch to saveCtx then to the SVC Handler after putting the PC + SVC into X0 and W1 and finally loadCtx before returning to where we were before
|
// If this is an SVC we need to branch to saveCtx then to the SVC Handler after putting the PC + SVC into X0 and W1 and finally loadCtx before returning to where we were before
|
||||||
instr::B bJunc(offset);
|
instr::B bJunc(offset);
|
||||||
|
|
||||||
constexpr u32 strLr = 0xF81F0FFE; // STR LR, [SP, #-16]!
|
constexpr u32 strLr{0xF81F0FFE}; // STR LR, [SP, #-16]!
|
||||||
offset += sizeof(strLr);
|
offset += sizeof(strLr);
|
||||||
|
|
||||||
instr::BL bSvCtx(patchOffset - offset);
|
instr::BL bSvCtx(patchOffset - offset);
|
||||||
offset += sizeof(bSvCtx);
|
offset += sizeof(bSvCtx);
|
||||||
|
|
||||||
auto movPc = instr::MoveRegister<u64>(regs::X0, baseAddress + (address - start));
|
auto movPc{instr::MoveRegister<u64>(regs::X0, baseAddress + (address - start))};
|
||||||
offset += sizeof(u32) * movPc.size();
|
offset += sizeof(u32) * movPc.size();
|
||||||
|
|
||||||
instr::Movz movCmd(regs::W1, static_cast<u16>(instrSvc->value));
|
instr::Movz movCmd(regs::W1, static_cast<u16>(instrSvc->value));
|
||||||
@ -263,7 +263,7 @@ namespace skyline {
|
|||||||
instr::BL bLdCtx((patchOffset + guest::SaveCtxSize) - offset);
|
instr::BL bLdCtx((patchOffset + guest::SaveCtxSize) - offset);
|
||||||
offset += sizeof(bLdCtx);
|
offset += sizeof(bLdCtx);
|
||||||
|
|
||||||
constexpr u32 ldrLr = 0xF84107FE; // LDR LR, [SP], #16
|
constexpr u32 ldrLr{0xF84107FE}; // LDR LR, [SP], #16
|
||||||
offset += sizeof(ldrLr);
|
offset += sizeof(ldrLr);
|
||||||
|
|
||||||
instr::B bret(-offset + sizeof(u32));
|
instr::B bret(-offset + sizeof(u32));
|
||||||
@ -290,7 +290,7 @@ namespace skyline {
|
|||||||
offset += sizeof(strX0);
|
offset += sizeof(strX0);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr u32 mrsX0 = 0xD53BD040; // MRS X0, TPIDR_EL0
|
constexpr u32 mrsX0{0xD53BD040}; // MRS X0, TPIDR_EL0
|
||||||
offset += sizeof(mrsX0);
|
offset += sizeof(mrsX0);
|
||||||
|
|
||||||
u32 ldrTls;
|
u32 ldrTls;
|
||||||
@ -335,14 +335,14 @@ namespace skyline {
|
|||||||
ldr.destReg = instrMrs->destReg;
|
ldr.destReg = instrMrs->destReg;
|
||||||
offset += sizeof(ldr);
|
offset += sizeof(ldr);
|
||||||
|
|
||||||
constexpr u32 addSp = 0x910083FF; // ADD SP, SP, #32
|
constexpr u32 addSp{0x910083FF}; // ADD SP, SP, #32
|
||||||
offset += sizeof(addSp);
|
offset += sizeof(addSp);
|
||||||
|
|
||||||
instr::B bret(-offset + sizeof(u32));
|
instr::B bret(-offset + sizeof(u32));
|
||||||
offset += sizeof(bret);
|
offset += sizeof(bret);
|
||||||
|
|
||||||
*address = bJunc.raw;
|
*address = bJunc.raw;
|
||||||
auto size = patch.size();
|
auto size{patch.size()};
|
||||||
patch.resize(size + (guest::RescaleClockSize / sizeof(u32)));
|
patch.resize(size + (guest::RescaleClockSize / sizeof(u32)));
|
||||||
std::memcpy(patch.data() + size, reinterpret_cast<void *>(&guest::RescaleClock), guest::RescaleClockSize);
|
std::memcpy(patch.data() + size, reinterpret_cast<void *>(&guest::RescaleClock), guest::RescaleClockSize);
|
||||||
patch.push_back(ldr.raw);
|
patch.push_back(ldr.raw);
|
||||||
@ -352,7 +352,7 @@ namespace skyline {
|
|||||||
// If this moves CNTFRQ_EL0 into a register then move the Tegra X1's clock frequency into the register (Rather than the host clock frequency)
|
// If this moves CNTFRQ_EL0 into a register then move the Tegra X1's clock frequency into the register (Rather than the host clock frequency)
|
||||||
instr::B bJunc(offset);
|
instr::B bJunc(offset);
|
||||||
|
|
||||||
auto movFreq = instr::MoveRegister<u32>(static_cast<regs::X>(instrMrs->destReg), TegraX1Freq);
|
auto movFreq{instr::MoveRegister<u32>(static_cast<regs::X>(instrMrs->destReg), TegraX1Freq)};
|
||||||
offset += sizeof(u32) * movFreq.size();
|
offset += sizeof(u32) * movFreq.size();
|
||||||
|
|
||||||
instr::B bret(-offset + sizeof(u32));
|
instr::B bret(-offset + sizeof(u32));
|
||||||
@ -376,22 +376,22 @@ namespace skyline {
|
|||||||
instr::B bJunc(offset);
|
instr::B bJunc(offset);
|
||||||
|
|
||||||
// Used to avoid conflicts as we cannot read the source register from the stack
|
// Used to avoid conflicts as we cannot read the source register from the stack
|
||||||
bool x0x1 = instrMrs->srcReg != regs::X0 && instrMrs->srcReg != regs::X1;
|
bool x0x1{instrMrs->srcReg != regs::X0 && instrMrs->srcReg != regs::X1};
|
||||||
|
|
||||||
// Push two registers to stack that can be used to load the TLS and arguments into
|
// Push two registers to stack that can be used to load the TLS and arguments into
|
||||||
u32 pushXn = x0x1 ? 0xA9BF07E0 : 0xA9BF0FE2; // STP X(0/2), X(1/3), [SP, #-16]!
|
u32 pushXn{x0x1 ? 0xA9BF07E0 : 0xA9BF0FE2}; // STP X(0/2), X(1/3), [SP, #-16]!
|
||||||
offset += sizeof(pushXn);
|
offset += sizeof(pushXn);
|
||||||
|
|
||||||
u32 loadRealTls = x0x1 ? 0xD53BD040 : 0xD53BD042; // MRS X(0/2), TPIDR_EL0
|
u32 loadRealTls{x0x1 ? 0xD53BD040 : 0xD53BD042}; // MRS X(0/2), TPIDR_EL0
|
||||||
offset += sizeof(loadRealTls);
|
offset += sizeof(loadRealTls);
|
||||||
|
|
||||||
instr::Mov moveParam(x0x1 ? regs::X1 : regs::X3, regs::X(instrMsr->srcReg));
|
instr::Mov moveParam(x0x1 ? regs::X1 : regs::X3, regs::X(instrMsr->srcReg));
|
||||||
offset += sizeof(moveParam);
|
offset += sizeof(moveParam);
|
||||||
|
|
||||||
u32 storeEmuTls = x0x1 ? 0xF9008401 : 0xF9008403; // STR X(1/3), [X0, #264] (ThreadContext::tpidrEl0)
|
u32 storeEmuTls{x0x1 ? 0xF9008401 : 0xF9008403}; // STR X(1/3), [X0, #264] (ThreadContext::tpidrEl0)
|
||||||
offset += sizeof(storeEmuTls);
|
offset += sizeof(storeEmuTls);
|
||||||
|
|
||||||
u32 popXn = x0x1 ? 0xA8C107E0 : 0xA8C10FE2; // LDP X(0/2), X(1/3), [SP], #16
|
u32 popXn{x0x1 ? 0xA8C107E0 : 0xA8C10FE2}; // LDP X(0/2), X(1/3), [SP], #16
|
||||||
offset += sizeof(popXn);
|
offset += sizeof(popXn);
|
||||||
|
|
||||||
instr::B bret(-offset + sizeof(u32));
|
instr::B bret(-offset + sizeof(u32));
|
||||||
|
@ -148,10 +148,10 @@ namespace skyline::guest {
|
|||||||
SaveCtxTls();
|
SaveCtxTls();
|
||||||
LoadCtxStack();
|
LoadCtxStack();
|
||||||
} else if (ctx->threadCall == ThreadCall::Memcopy) {
|
} else if (ctx->threadCall == ThreadCall::Memcopy) {
|
||||||
auto src = reinterpret_cast<u8 *>(ctx->registers.x0);
|
auto src{reinterpret_cast<u8 *>(ctx->registers.x0)};
|
||||||
auto dest = reinterpret_cast<u8 *>(ctx->registers.x1);
|
auto dest{reinterpret_cast<u8 *>(ctx->registers.x1)};
|
||||||
auto size = ctx->registers.x2;
|
auto size{ctx->registers.x2};
|
||||||
auto end = src + size;
|
auto end{src + size};
|
||||||
|
|
||||||
while (src < end)
|
while (src < end)
|
||||||
*(src++) = *(dest++);
|
*(src++) = *(dest++);
|
||||||
@ -220,7 +220,7 @@ namespace skyline::guest {
|
|||||||
volatile ThreadContext *ctx;
|
volatile ThreadContext *ctx;
|
||||||
asm("MRS %0, TPIDR_EL0":"=r"(ctx));
|
asm("MRS %0, TPIDR_EL0":"=r"(ctx));
|
||||||
|
|
||||||
for (u8 index = 0; index < 30; index++)
|
for (u8 index{}; index < 30; index++)
|
||||||
ctx->registers.regs[index] = ucontext->uc_mcontext.regs[index];
|
ctx->registers.regs[index] = ucontext->uc_mcontext.regs[index];
|
||||||
|
|
||||||
ctx->pc = ucontext->uc_mcontext.pc;
|
ctx->pc = ucontext->uc_mcontext.pc;
|
||||||
@ -261,10 +261,10 @@ namespace skyline::guest {
|
|||||||
LoadCtxStack();
|
LoadCtxStack();
|
||||||
}
|
}
|
||||||
} else if (ctx->threadCall == ThreadCall::Memcopy) {
|
} else if (ctx->threadCall == ThreadCall::Memcopy) {
|
||||||
auto src = reinterpret_cast<u8 *>(ctx->registers.x0);
|
auto src{reinterpret_cast<u8 *>(ctx->registers.x0)};
|
||||||
auto dest = reinterpret_cast<u8 *>(ctx->registers.x1);
|
auto dest{reinterpret_cast<u8 *>(ctx->registers.x1)};
|
||||||
auto size = ctx->registers.x2;
|
auto size{ctx->registers.x2};
|
||||||
auto end = src + size;
|
auto end{src + size};
|
||||||
|
|
||||||
while (src < end)
|
while (src < end)
|
||||||
*(src++) = *(dest++);
|
*(src++) = *(dest++);
|
||||||
|
@ -7,13 +7,13 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace guest {
|
namespace guest {
|
||||||
constexpr size_t SaveCtxSize = 20 * sizeof(u32); //!< The size of the SaveCtx function in 32-bit ARMv8 instructions
|
constexpr size_t SaveCtxSize{20 * sizeof(u32)}; //!< The size of the SaveCtx function in 32-bit ARMv8 instructions
|
||||||
constexpr size_t LoadCtxSize = 20 * sizeof(u32); //!< The size of the LoadCtx function in 32-bit ARMv8 instructions
|
constexpr size_t LoadCtxSize{20 * sizeof(u32)}; //!< The size of the LoadCtx function in 32-bit ARMv8 instructions
|
||||||
constexpr size_t RescaleClockSize = 16 * sizeof(u32); //!< The size of the RescaleClock function in 32-bit ARMv8 instructions
|
constexpr size_t RescaleClockSize{16 * sizeof(u32)}; //!< The size of the RescaleClock function in 32-bit ARMv8 instructions
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
constexpr size_t SvcHandlerSize = 225 * sizeof(u32); //!< The size of the SvcHandler (Release) function in 32-bit ARMv8 instructions
|
constexpr size_t SvcHandlerSize{225 * sizeof(u32)}; //!< The size of the SvcHandler (Release) function in 32-bit ARMv8 instructions
|
||||||
#else
|
#else
|
||||||
constexpr size_t SvcHandlerSize = 400 * sizeof(u32); //!< The size of the SvcHandler (Debug) function in 32-bit ARMv8 instructions
|
constexpr size_t SvcHandlerSize{400 * sizeof(u32)}; //!< The size of the SvcHandler (Debug) function in 32-bit ARMv8 instructions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -337,7 +337,7 @@ namespace skyline {
|
|||||||
inline constexpr std::array<u32, sizeof(Type) / sizeof(u16)> MoveRegister(regs::X destination, Type value) {
|
inline constexpr std::array<u32, sizeof(Type) / sizeof(u16)> MoveRegister(regs::X destination, Type value) {
|
||||||
std::array<u32, sizeof(Type) / sizeof(u16)> instructions;
|
std::array<u32, sizeof(Type) / sizeof(u16)> instructions;
|
||||||
|
|
||||||
auto valuePointer = reinterpret_cast<u16 *>(&value);
|
auto valuePointer{reinterpret_cast<u16 *>(&value)};
|
||||||
u8 offset{};
|
u8 offset{};
|
||||||
|
|
||||||
for (auto &instruction : instructions) {
|
for (auto &instruction : instructions) {
|
||||||
|
@ -9,7 +9,7 @@ namespace skyline::service::account {
|
|||||||
IAccountServiceForApplication::IAccountServiceForApplication(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
IAccountServiceForApplication::IAccountServiceForApplication(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IAccountServiceForApplication::GetUserExistence(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IAccountServiceForApplication::GetUserExistence(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto id = request.Pop<UserId>();
|
auto id{request.Pop<UserId>()};
|
||||||
|
|
||||||
// ID can't be zero
|
// ID can't be zero
|
||||||
if (id == UserId{})
|
if (id == UserId{})
|
||||||
@ -60,7 +60,7 @@ namespace skyline::service::account {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IAccountServiceForApplication::GetProfile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IAccountServiceForApplication::GetProfile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto id = request.Pop<UserId>();
|
auto id{request.Pop<UserId>()};
|
||||||
if (id != constant::DefaultUserId)
|
if (id != constant::DefaultUserId)
|
||||||
return result::UserNotFound;
|
return result::UserNotFound;
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ namespace skyline::service::account {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IAccountServiceForApplication::GetBaasAccountManagerForApplication(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IAccountServiceForApplication::GetBaasAccountManagerForApplication(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto id = request.Pop<UserId>();
|
auto id{request.Pop<UserId>()};
|
||||||
if (id == UserId{})
|
if (id == UserId{})
|
||||||
return result::NullArgument;
|
return result::NullArgument;
|
||||||
|
|
||||||
|
@ -91,6 +91,6 @@ namespace skyline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr service::account::UserId DefaultUserId = {0x0000000000000001, 0x0000000000000000}; //!< The default user ID
|
constexpr service::account::UserId DefaultUserId{0x0000000000000001, 0x0000000000000000}; //!< The default user ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,8 @@ namespace skyline::service::account {
|
|||||||
.uid = userId
|
.uid = userId
|
||||||
};
|
};
|
||||||
|
|
||||||
auto username = state.settings->GetString("username_value");
|
auto username{state.settings->GetString("username_value")};
|
||||||
size_t usernameSize = std::min(accountProfileBase.nickname.size() - 1, username.size());
|
size_t usernameSize{std::min(accountProfileBase.nickname.size() - 1, username.size())};
|
||||||
std::memcpy(accountProfileBase.nickname.data(), username.c_str(), usernameSize);
|
std::memcpy(accountProfileBase.nickname.data(), username.c_str(), usernameSize);
|
||||||
|
|
||||||
response.Push(accountProfileBase);
|
response.Push(accountProfileBase);
|
||||||
|
@ -12,7 +12,7 @@ namespace skyline::service::am {
|
|||||||
Result ILibraryAppletAccessor::GetAppletStateChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ILibraryAppletAccessor::GetAppletStateChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
stateChangeEvent->Signal();
|
stateChangeEvent->Signal();
|
||||||
|
|
||||||
KHandle handle = state.process->InsertItem(stateChangeEvent);
|
KHandle handle{state.process->InsertItem(stateChangeEvent)};
|
||||||
state.logger->Debug("Applet State Change Event Handle: 0x{:X}", handle);
|
state.logger->Debug("Applet State Change Event Handle: 0x{:X}", handle);
|
||||||
|
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
@ -32,10 +32,10 @@ namespace skyline::service::am {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result ILibraryAppletAccessor::PopOutData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ILibraryAppletAccessor::PopOutData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
constexpr u32 LaunchParameterMagic = 0xC79497CA; //!< This is the magic of the application launch parameters
|
constexpr u32 LaunchParameterMagic{0xC79497CA}; //!< This is the magic of the application launch parameters
|
||||||
constexpr size_t LaunchParameterSize = 0x88; //!< This is the size of the launch parameter IStorage
|
constexpr size_t LaunchParameterSize{0x88}; //!< This is the size of the launch parameter IStorage
|
||||||
|
|
||||||
auto storageService = std::make_shared<IStorage>(state, manager, LaunchParameterSize);
|
auto storageService{std::make_shared<IStorage>(state, manager, LaunchParameterSize)};
|
||||||
|
|
||||||
storageService->Push<u32>(LaunchParameterMagic);
|
storageService->Push<u32>(LaunchParameterMagic);
|
||||||
storageService->Push<u32>(1);
|
storageService->Push<u32>(1);
|
||||||
|
@ -10,10 +10,10 @@ namespace skyline::service::am {
|
|||||||
IApplicationFunctions::IApplicationFunctions(const DeviceState &state, ServiceManager &manager) : gpuErrorEvent(std::make_shared<type::KEvent>(state)), BaseService(state, manager) {}
|
IApplicationFunctions::IApplicationFunctions(const DeviceState &state, ServiceManager &manager) : gpuErrorEvent(std::make_shared<type::KEvent>(state)), BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IApplicationFunctions::PopLaunchParameter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IApplicationFunctions::PopLaunchParameter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
constexpr u32 LaunchParameterMagic = 0xC79497CA; //!< This is the magic of the application launch parameters
|
constexpr u32 LaunchParameterMagic{0xC79497CA}; //!< This is the magic of the application launch parameters
|
||||||
constexpr size_t LaunchParameterSize = 0x88; //!< This is the size of the launch parameter IStorage
|
constexpr size_t LaunchParameterSize{0x88}; //!< This is the size of the launch parameter IStorage
|
||||||
|
|
||||||
auto storageService = std::make_shared<IStorage>(state, manager, LaunchParameterSize);
|
auto storageService{std::make_shared<IStorage>(state, manager, LaunchParameterSize)};
|
||||||
|
|
||||||
storageService->Push<u32>(LaunchParameterMagic);
|
storageService->Push<u32>(LaunchParameterMagic);
|
||||||
storageService->Push<u32>(1);
|
storageService->Push<u32>(1);
|
||||||
@ -53,7 +53,7 @@ namespace skyline::service::am {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IApplicationFunctions::GetGpuErrorDetectedSystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IApplicationFunctions::GetGpuErrorDetectedSystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto handle = state.process->InsertItem(gpuErrorEvent);
|
auto handle{state.process->InsertItem(gpuErrorEvent)};
|
||||||
state.logger->Debug("GPU Error Event Handle: 0x{:X}", handle);
|
state.logger->Debug("GPU Error Event Handle: 0x{:X}", handle);
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
return {};
|
return {};
|
||||||
|
@ -17,7 +17,7 @@ namespace skyline::service::am {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result ICommonStateGetter::GetEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ICommonStateGetter::GetEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto handle = state.process->InsertItem(messageEvent);
|
auto handle{state.process->InsertItem(messageEvent)};
|
||||||
state.logger->Debug("Applet Event Handle: 0x{:X}", handle);
|
state.logger->Debug("Applet Event Handle: 0x{:X}", handle);
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
return {};
|
return {};
|
||||||
|
@ -14,7 +14,7 @@ namespace skyline::service::am {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result ILibraryAppletCreator::CreateStorage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ILibraryAppletCreator::CreateStorage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto size = request.Pop<i64>();
|
auto size{request.Pop<i64>()};
|
||||||
|
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
throw exception("Cannot create an IStorage with a negative size");
|
throw exception("Cannot create an IStorage with a negative size");
|
||||||
|
@ -19,7 +19,7 @@ namespace skyline::service::am {
|
|||||||
Result ISelfController::GetLibraryAppletLaunchableEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ISelfController::GetLibraryAppletLaunchableEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
libraryAppletLaunchableEvent->Signal();
|
libraryAppletLaunchableEvent->Signal();
|
||||||
|
|
||||||
KHandle handle = state.process->InsertItem(libraryAppletLaunchableEvent);
|
KHandle handle{state.process->InsertItem(libraryAppletLaunchableEvent)};
|
||||||
state.logger->Debug("Library Applet Launchable Event Handle: 0x{:X}", handle);
|
state.logger->Debug("Library Applet Launchable Event Handle: 0x{:X}", handle);
|
||||||
|
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
@ -49,7 +49,7 @@ namespace skyline::service::am {
|
|||||||
Result ISelfController::CreateManagedDisplayLayer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ISelfController::CreateManagedDisplayLayer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
state.logger->Debug("Creating Managed Layer on Default Display");
|
state.logger->Debug("Creating Managed Layer on Default Display");
|
||||||
|
|
||||||
auto producer = hosbinder::producer.lock();
|
auto producer{hosbinder::producer.lock()};
|
||||||
if (producer->layerStatus != hosbinder::LayerStatus::Uninitialized)
|
if (producer->layerStatus != hosbinder::LayerStatus::Uninitialized)
|
||||||
throw exception("The application is creating more than one layer");
|
throw exception("The application is creating more than one layer");
|
||||||
producer->layerStatus = hosbinder::LayerStatus::Managed;
|
producer->layerStatus = hosbinder::LayerStatus::Managed;
|
||||||
@ -59,7 +59,7 @@ namespace skyline::service::am {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result ISelfController::GetAccumulatedSuspendedTickChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ISelfController::GetAccumulatedSuspendedTickChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto handle = state.process->InsertItem(accumulatedSuspendedTickChangedEvent);
|
auto handle{state.process->InsertItem(accumulatedSuspendedTickChangedEvent)};
|
||||||
state.logger->Debug("Accumulated Suspended Tick Event Handle: 0x{:X}", handle);
|
state.logger->Debug("Accumulated Suspended Tick Event Handle: 0x{:X}", handle);
|
||||||
|
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
|
@ -13,8 +13,8 @@ namespace skyline::service::am {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IStorageAccessor::Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IStorageAccessor::Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto offset = request.Pop<i64>();
|
auto offset{request.Pop<i64>()};
|
||||||
auto size = std::min(static_cast<i64>(request.inputBuf.at(0).size()), static_cast<i64>(parent->content.size()) - offset);
|
auto size{std::min(static_cast<i64>(request.inputBuf.at(0).size()), static_cast<i64>(parent->content.size()) - offset)};
|
||||||
|
|
||||||
if (offset > parent->content.size())
|
if (offset > parent->content.size())
|
||||||
return result::OutOfBounds;
|
return result::OutOfBounds;
|
||||||
@ -26,8 +26,8 @@ namespace skyline::service::am {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IStorageAccessor::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IStorageAccessor::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto offset = request.Pop<i64>();
|
auto offset{request.Pop<i64>()};
|
||||||
auto size = std::min(static_cast<i64>(request.inputBuf.at(0).size()), static_cast<i64>(parent->content.size()) - offset);
|
auto size{std::min(static_cast<i64>(request.inputBuf.at(0).size()), static_cast<i64>(parent->content.size()) - offset)};
|
||||||
|
|
||||||
if (offset > parent->content.size())
|
if (offset > parent->content.size())
|
||||||
return result::OutOfBounds;
|
return result::OutOfBounds;
|
||||||
|
@ -7,15 +7,15 @@ namespace skyline::service::apm {
|
|||||||
ISession::ISession(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
ISession::ISession(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
||||||
|
|
||||||
Result ISession::SetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ISession::SetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto mode = request.Pop<u32>();
|
auto mode{request.Pop<u32>()};
|
||||||
auto config = request.Pop<u32>();
|
auto config{request.Pop<u32>()};
|
||||||
performanceConfig.at(mode) = config;
|
performanceConfig.at(mode) = config;
|
||||||
state.logger->Info("Performance configuration set to 0x{:X} ({})", config, mode ? "Docked" : "Handheld");
|
state.logger->Info("Performance configuration set to 0x{:X} ({})", config, mode ? "Docked" : "Handheld");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ISession::GetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ISession::GetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto performanceMode = request.Pop<u32>();
|
auto performanceMode{request.Pop<u32>()};
|
||||||
response.Push<u32>(performanceConfig.at(performanceMode));
|
response.Push<u32>(performanceConfig.at(performanceMode));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -38,12 +38,12 @@ namespace skyline::service::audio {
|
|||||||
u64 sampleSize;
|
u64 sampleSize;
|
||||||
u64 sampleOffset;
|
u64 sampleOffset;
|
||||||
} &data{request.inputBuf.at(0).as<Data>()};
|
} &data{request.inputBuf.at(0).as<Data>()};
|
||||||
auto tag = request.Pop<u64>();
|
auto tag{request.Pop<u64>()};
|
||||||
|
|
||||||
state.logger->Debug("Appending buffer with address: 0x{:X}, size: 0x{:X}", data.sampleBufferPtr, data.sampleSize);
|
state.logger->Debug("Appending buffer with address: 0x{:X}, size: 0x{:X}", data.sampleBufferPtr, data.sampleSize);
|
||||||
|
|
||||||
if (sampleRate != constant::SampleRate) {
|
if (sampleRate != constant::SampleRate) {
|
||||||
auto resampledBuffer = resampler.ResampleBuffer(span(state.process->GetPointer<i16>(data.sampleBufferPtr), data.sampleSize / sizeof(i16)), static_cast<double>(sampleRate) / constant::SampleRate, channelCount);
|
auto resampledBuffer{resampler.ResampleBuffer(span(state.process->GetPointer<i16>(data.sampleBufferPtr), data.sampleSize / sizeof(i16)), static_cast<double>(sampleRate) / constant::SampleRate, channelCount)};
|
||||||
track->AppendBuffer(tag, resampledBuffer);
|
track->AppendBuffer(tag, resampledBuffer);
|
||||||
} else {
|
} else {
|
||||||
track->AppendBuffer(tag, span(state.process->GetPointer<i16>(data.sampleBufferPtr), data.sampleSize / sizeof(i16)));
|
track->AppendBuffer(tag, span(state.process->GetPointer<i16>(data.sampleBufferPtr), data.sampleSize / sizeof(i16)));
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr std::string_view DefaultAudioOutName = "DeviceOut"; //!< The default audio output device name
|
constexpr std::string_view DefaultAudioOutName{"DeviceOut"}; //!< The default audio output device name
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace service::audio {
|
namespace service::audio {
|
||||||
|
@ -54,18 +54,18 @@ namespace skyline::service::audio::IAudioRenderer {
|
|||||||
|
|
||||||
span memoryPoolsIn(reinterpret_cast<MemoryPoolIn*>(input), memoryPools.size());
|
span memoryPoolsIn(reinterpret_cast<MemoryPoolIn*>(input), memoryPools.size());
|
||||||
input += inputHeader.memoryPoolSize;
|
input += inputHeader.memoryPoolSize;
|
||||||
for (auto i = 0; i < memoryPools.size(); i++)
|
for (size_t i{}; i < memoryPools.size(); i++)
|
||||||
memoryPools[i].ProcessInput(memoryPoolsIn[i]);
|
memoryPools[i].ProcessInput(memoryPoolsIn[i]);
|
||||||
|
|
||||||
input += inputHeader.voiceResourceSize;
|
input += inputHeader.voiceResourceSize;
|
||||||
|
|
||||||
span voicesIn(reinterpret_cast<VoiceIn*>(input), parameters.voiceCount);
|
span voicesIn(reinterpret_cast<VoiceIn*>(input), parameters.voiceCount);
|
||||||
input += inputHeader.voiceSize;
|
input += inputHeader.voiceSize;
|
||||||
for (auto i = 0; i < voicesIn.size(); i++)
|
for (u32 i{}; i < voicesIn.size(); i++)
|
||||||
voices[i].ProcessInput(voicesIn[i]);
|
voices[i].ProcessInput(voicesIn[i]);
|
||||||
|
|
||||||
span effectsIn(reinterpret_cast<EffectIn*>(input), parameters.effectCount);
|
span effectsIn(reinterpret_cast<EffectIn*>(input), parameters.effectCount);
|
||||||
for (auto i = 0; i < effectsIn.size(); i++)
|
for (u32 i{}; i < effectsIn.size(); i++)
|
||||||
effects[i].ProcessInput(effectsIn[i]);
|
effects[i].ProcessInput(effectsIn[i]);
|
||||||
|
|
||||||
UpdateAudio();
|
UpdateAudio();
|
||||||
@ -127,14 +127,14 @@ namespace skyline::service::audio::IAudioRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IAudioRenderer::MixFinalBuffer() {
|
void IAudioRenderer::MixFinalBuffer() {
|
||||||
u32 writtenSamples = 0;
|
u32 writtenSamples{};
|
||||||
|
|
||||||
for (auto &voice : voices) {
|
for (auto &voice : voices) {
|
||||||
if (!voice.Playable())
|
if (!voice.Playable())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u32 bufferOffset{};
|
u32 bufferOffset{};
|
||||||
u32 pendingSamples = constant::MixBufferSize;
|
u32 pendingSamples{constant::MixBufferSize};
|
||||||
|
|
||||||
while (pendingSamples > 0) {
|
while (pendingSamples > 0) {
|
||||||
u32 voiceBufferOffset{};
|
u32 voiceBufferOffset{};
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr auto BufferAlignment = 0x40; //!< The alignment for all audren buffers
|
constexpr u8 BufferAlignment{0x40}; //!< The alignment for all audren buffers
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace service::audio::IAudioRenderer {
|
namespace service::audio::IAudioRenderer {
|
||||||
|
@ -35,7 +35,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
|||||||
* @brief This is returned to inform the guest of the state of a memory pool
|
* @brief This is returned to inform the guest of the state of a memory pool
|
||||||
*/
|
*/
|
||||||
struct MemoryPoolOut {
|
struct MemoryPoolOut {
|
||||||
MemoryPoolState state = MemoryPoolState::Detached;
|
MemoryPoolState state{MemoryPoolState::Detached};
|
||||||
u32 _unk0_;
|
u32 _unk0_;
|
||||||
u64 _unk1_;
|
u64 _unk1_;
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@ namespace skyline::service::audio {
|
|||||||
IAudioRendererManager::IAudioRendererManager(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
IAudioRendererManager::IAudioRendererManager(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IAudioRendererManager::OpenAudioRenderer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IAudioRendererManager::OpenAudioRenderer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
IAudioRenderer::AudioRendererParameters params = request.Pop<IAudioRenderer::AudioRendererParameters>();
|
IAudioRenderer::AudioRendererParameters params{request.Pop<IAudioRenderer::AudioRendererParameters>()};
|
||||||
|
|
||||||
state.logger->Debug("IAudioRendererManager: Opening a rev {} IAudioRenderer with sample rate: {}, voice count: {}, effect count: {}", IAudioRenderer::ExtractVersionFromRevision(params.revision), params.sampleRate, params.voiceCount, params.effectCount);
|
state.logger->Debug("IAudioRendererManager: Opening a rev {} IAudioRenderer with sample rate: {}, voice count: {}, effect count: {}", IAudioRenderer::ExtractVersionFromRevision(params.revision), params.sampleRate, params.voiceCount, params.effectCount);
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ namespace skyline::service::audio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IAudioRendererManager::GetAudioRendererWorkBufferSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IAudioRendererManager::GetAudioRendererWorkBufferSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
IAudioRenderer::AudioRendererParameters params = request.Pop<IAudioRenderer::AudioRendererParameters>();
|
IAudioRenderer::AudioRendererParameters params{request.Pop<IAudioRenderer::AudioRendererParameters>()};
|
||||||
|
|
||||||
IAudioRenderer::RevisionInfo revisionInfo{};
|
IAudioRenderer::RevisionInfo revisionInfo{};
|
||||||
revisionInfo.SetUserRevision(params.revision);
|
revisionInfo.SetUserRevision(params.revision);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
namespace skyline::service {
|
namespace skyline::service {
|
||||||
const std::string &BaseService::GetName() {
|
const std::string &BaseService::GetName() {
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
auto mangledName = typeid(*this).name();
|
auto mangledName{typeid(*this).name()};
|
||||||
|
|
||||||
int status{};
|
int status{};
|
||||||
size_t length{};
|
size_t length{};
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#define SERVICE_DECL(...) \
|
#define SERVICE_DECL(...) \
|
||||||
SERVICE_DECL_AUTO(functions, frz::make_unordered_map({__VA_ARGS__})); \
|
SERVICE_DECL_AUTO(functions, frz::make_unordered_map({__VA_ARGS__})); \
|
||||||
std::pair<std::function<Result(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>, std::string_view> GetServiceFunction(u32 id) { \
|
std::pair<std::function<Result(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>, std::string_view> GetServiceFunction(u32 id) { \
|
||||||
auto& function = functions.at(id); \
|
auto& function{functions.at(id)}; \
|
||||||
return std::make_pair(std::bind(function.first, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), function.second); \
|
return std::make_pair(std::bind(function.first, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), function.second); \
|
||||||
}
|
}
|
||||||
#define SRVREG(class, ...) std::make_shared<class>(state, manager, ##__VA_ARGS__)
|
#define SRVREG(class, ...) std::make_shared<class>(state, manager, ##__VA_ARGS__)
|
||||||
|
@ -10,7 +10,7 @@ namespace skyline::service {
|
|||||||
if (buffer.size() < (sizeof(ParcelHeader) + header.dataSize + header.objectsSize))
|
if (buffer.size() < (sizeof(ParcelHeader) + header.dataSize + header.objectsSize))
|
||||||
throw exception("The size of the parcel according to the header exceeds the specified size");
|
throw exception("The size of the parcel according to the header exceeds the specified size");
|
||||||
|
|
||||||
constexpr auto tokenLength = 0x50; // The length of the token on BufferQueue parcels
|
constexpr u8 tokenLength{0x50}; // The length of the token on BufferQueue parcels
|
||||||
|
|
||||||
data.resize(header.dataSize - (hasToken ? tokenLength : 0));
|
data.resize(header.dataSize - (hasToken ? tokenLength : 0));
|
||||||
memcpy(data.data(), buffer.data() + header.dataOffset + (hasToken ? tokenLength : 0), header.dataSize - (hasToken ? tokenLength : 0));
|
memcpy(data.data(), buffer.data() + header.dataOffset + (hasToken ? tokenLength : 0), header.dataSize - (hasToken ? tokenLength : 0));
|
||||||
@ -28,7 +28,7 @@ namespace skyline::service {
|
|||||||
header.objectsSize = static_cast<u32>(objects.size());
|
header.objectsSize = static_cast<u32>(objects.size());
|
||||||
header.objectsOffset = sizeof(ParcelHeader) + data.size();
|
header.objectsOffset = sizeof(ParcelHeader) + data.size();
|
||||||
|
|
||||||
auto totalSize = sizeof(ParcelHeader) + header.dataSize + header.objectsSize;
|
auto totalSize{sizeof(ParcelHeader) + header.dataSize + header.objectsSize};
|
||||||
|
|
||||||
if (buffer.size() < totalSize)
|
if (buffer.size() < totalSize)
|
||||||
throw exception("The size of the parcel exceeds maxSize");
|
throw exception("The size of the parcel exceeds maxSize");
|
||||||
|
@ -48,7 +48,7 @@ namespace skyline::service {
|
|||||||
*/
|
*/
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
inline ValueType &Pop() {
|
inline ValueType &Pop() {
|
||||||
ValueType &value = *reinterpret_cast<ValueType *>(data.data() + dataOffset);
|
ValueType &value{*reinterpret_cast<ValueType *>(data.data() + dataOffset)};
|
||||||
dataOffset += sizeof(ValueType);
|
dataOffset += sizeof(ValueType);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ namespace skyline::service {
|
|||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
void Push(const ValueType &value) {
|
void Push(const ValueType &value) {
|
||||||
data.reserve(data.size() + sizeof(ValueType));
|
data.reserve(data.size() + sizeof(ValueType));
|
||||||
auto item = reinterpret_cast<const u8 *>(&value);
|
auto item{reinterpret_cast<const u8 *>(&value)};
|
||||||
for (size_t index{}; sizeof(ValueType) > index; index++) {
|
for (size_t index{}; sizeof(ValueType) > index; index++) {
|
||||||
data.push_back(*item);
|
data.push_back(*item);
|
||||||
item++;
|
item++;
|
||||||
@ -76,7 +76,7 @@ namespace skyline::service {
|
|||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
void PushObject(const ValueType &value) {
|
void PushObject(const ValueType &value) {
|
||||||
objects.reserve(objects.size() + sizeof(ValueType));
|
objects.reserve(objects.size() + sizeof(ValueType));
|
||||||
auto item = reinterpret_cast<const u8 *>(&value);
|
auto item{reinterpret_cast<const u8 *>(&value)};
|
||||||
for (size_t index{}; sizeof(ValueType) > index; index++) {
|
for (size_t index{}; sizeof(ValueType) > index; index++) {
|
||||||
objects.push_back(*item);
|
objects.push_back(*item);
|
||||||
item++;
|
item++;
|
||||||
|
@ -8,7 +8,7 @@ namespace skyline::service::friends {
|
|||||||
INotificationService::INotificationService(const DeviceState &state, ServiceManager &manager) : notificationEvent(std::make_shared<type::KEvent>(state)), BaseService(state, manager) {}
|
INotificationService::INotificationService(const DeviceState &state, ServiceManager &manager) : notificationEvent(std::make_shared<type::KEvent>(state)), BaseService(state, manager) {}
|
||||||
|
|
||||||
Result INotificationService::GetEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result INotificationService::GetEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
KHandle handle = state.process->InsertItem(notificationEvent);
|
KHandle handle{state.process->InsertItem(notificationEvent)};
|
||||||
state.logger->Debug("Friend Notification Event Handle: 0x{:X}", handle);
|
state.logger->Debug("Friend Notification Event Handle: 0x{:X}", handle);
|
||||||
|
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
|
@ -8,10 +8,10 @@ namespace skyline::service::fssrv {
|
|||||||
IFile::IFile(std::shared_ptr<vfs::Backing> &backing, const DeviceState &state, ServiceManager &manager) : backing(backing), BaseService(state, manager) {}
|
IFile::IFile(std::shared_ptr<vfs::Backing> &backing, const DeviceState &state, ServiceManager &manager) : backing(backing), BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IFile::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IFile::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto readOption = request.Pop<u32>();
|
auto readOption{request.Pop<u32>()};
|
||||||
request.Skip<u32>();
|
request.Skip<u32>();
|
||||||
auto offset = request.Pop<i64>();
|
auto offset{request.Pop<i64>()};
|
||||||
auto size = request.Pop<i64>();
|
auto size{request.Pop<i64>()};
|
||||||
|
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
state.logger->Warn("Trying to read a file with a negative offset");
|
state.logger->Warn("Trying to read a file with a negative offset");
|
||||||
@ -28,10 +28,10 @@ namespace skyline::service::fssrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IFile::Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IFile::Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto writeOption = request.Pop<u32>();
|
auto writeOption{request.Pop<u32>()};
|
||||||
request.Skip<u32>();
|
request.Skip<u32>();
|
||||||
auto offset = request.Pop<i64>();
|
auto offset{request.Pop<i64>()};
|
||||||
auto size = request.Pop<i64>();
|
auto size{request.Pop<i64>()};
|
||||||
|
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
state.logger->Warn("Trying to write to a file with a negative offset");
|
state.logger->Warn("Trying to write to a file with a negative offset");
|
||||||
|
@ -10,8 +10,8 @@ namespace skyline::service::fssrv {
|
|||||||
|
|
||||||
Result IFileSystem::CreateFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IFileSystem::CreateFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
std::string path{request.inputBuf.at(0).as<char>()};
|
std::string path{request.inputBuf.at(0).as<char>()};
|
||||||
auto mode = request.Pop<u64>();
|
auto mode{request.Pop<u64>()};
|
||||||
auto size = request.Pop<u32>();
|
auto size{request.Pop<u32>()};
|
||||||
|
|
||||||
return backing->CreateFile(path, size) ? Result{} : result::PathDoesNotExist;
|
return backing->CreateFile(path, size) ? Result{} : result::PathDoesNotExist;
|
||||||
}
|
}
|
||||||
@ -19,7 +19,7 @@ namespace skyline::service::fssrv {
|
|||||||
Result IFileSystem::GetEntryType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IFileSystem::GetEntryType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
std::string path{request.inputBuf.at(0).as<char>()};
|
std::string path{request.inputBuf.at(0).as<char>()};
|
||||||
|
|
||||||
auto type = backing->GetEntryType(path);
|
auto type{backing->GetEntryType(path)};
|
||||||
|
|
||||||
if (type) {
|
if (type) {
|
||||||
response.Push(*type);
|
response.Push(*type);
|
||||||
@ -32,12 +32,12 @@ namespace skyline::service::fssrv {
|
|||||||
|
|
||||||
Result IFileSystem::OpenFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IFileSystem::OpenFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
std::string path{request.inputBuf.at(0).as<char>()};
|
std::string path{request.inputBuf.at(0).as<char>()};
|
||||||
auto mode = request.Pop<vfs::Backing::Mode>();
|
auto mode{request.Pop<vfs::Backing::Mode>()};
|
||||||
|
|
||||||
if (!backing->FileExists(path))
|
if (!backing->FileExists(path))
|
||||||
return result::PathDoesNotExist;
|
return result::PathDoesNotExist;
|
||||||
|
|
||||||
auto file = backing->OpenFile(path, mode);
|
auto file{backing->OpenFile(path, mode)};
|
||||||
if (file == nullptr)
|
if (file == nullptr)
|
||||||
return result::UnexpectedFailure;
|
return result::UnexpectedFailure;
|
||||||
else
|
else
|
||||||
|
@ -22,14 +22,14 @@ namespace skyline::service::fssrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IFileSystemProxy::OpenSaveDataFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IFileSystemProxy::OpenSaveDataFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto spaceId = request.Pop<SaveDataSpaceId>();
|
auto spaceId{request.Pop<SaveDataSpaceId>()};
|
||||||
auto attribute = request.Pop<SaveDataAttribute>();
|
auto attribute{request.Pop<SaveDataAttribute>()};
|
||||||
|
|
||||||
if (attribute.programId == 0)
|
if (attribute.programId == 0)
|
||||||
attribute.programId = state.loader->nacp->nacpContents.saveDataOwnerId;
|
attribute.programId = state.loader->nacp->nacpContents.saveDataOwnerId;
|
||||||
|
|
||||||
std::string saveDataPath = [spaceId, &attribute]() {
|
std::string saveDataPath{[spaceId, &attribute]() {
|
||||||
std::string spaceIdStr = [spaceId]() {
|
std::string spaceIdStr{[spaceId]() {
|
||||||
switch (spaceId) {
|
switch (spaceId) {
|
||||||
case SaveDataSpaceId::System:
|
case SaveDataSpaceId::System:
|
||||||
return "/nand/system";
|
return "/nand/system";
|
||||||
@ -40,7 +40,7 @@ namespace skyline::service::fssrv {
|
|||||||
default:
|
default:
|
||||||
throw exception("Unsupported savedata ID: {}", spaceId);
|
throw exception("Unsupported savedata ID: {}", spaceId);
|
||||||
};
|
};
|
||||||
}();
|
}()};
|
||||||
|
|
||||||
switch (attribute.type) {
|
switch (attribute.type) {
|
||||||
case SaveDataType::System:
|
case SaveDataType::System:
|
||||||
@ -55,7 +55,7 @@ namespace skyline::service::fssrv {
|
|||||||
default:
|
default:
|
||||||
throw exception("Unsupported savedata type: {}", attribute.type);
|
throw exception("Unsupported savedata type: {}", attribute.type);
|
||||||
};
|
};
|
||||||
}();
|
}()};
|
||||||
|
|
||||||
manager.RegisterService(std::make_shared<IFileSystem>(std::make_shared<vfs::OsFileSystem>(state.os->appFilesPath + "/switch" + saveDataPath), state, manager), session, response);
|
manager.RegisterService(std::make_shared<IFileSystem>(std::make_shared<vfs::OsFileSystem>(state.os->appFilesPath + "/switch" + saveDataPath), state, manager), session, response);
|
||||||
return {};
|
return {};
|
||||||
|
@ -8,8 +8,8 @@ namespace skyline::service::fssrv {
|
|||||||
IStorage::IStorage(std::shared_ptr<vfs::Backing> &backing, const DeviceState &state, ServiceManager &manager) : backing(backing), BaseService(state, manager) {}
|
IStorage::IStorage(std::shared_ptr<vfs::Backing> &backing, const DeviceState &state, ServiceManager &manager) : backing(backing), BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IStorage::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IStorage::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto offset = request.Pop<i64>();
|
auto offset{request.Pop<i64>()};
|
||||||
auto size = request.Pop<i64>();
|
auto size{request.Pop<i64>()};
|
||||||
|
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
state.logger->Warn("Trying to read a file with a negative offset");
|
state.logger->Warn("Trying to read a file with a negative offset");
|
||||||
|
@ -10,7 +10,7 @@ namespace skyline::service::hid {
|
|||||||
IActiveVibrationDeviceList::IActiveVibrationDeviceList(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
IActiveVibrationDeviceList::IActiveVibrationDeviceList(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IActiveVibrationDeviceList::ActivateVibrationDevice(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IActiveVibrationDeviceList::ActivateVibrationDevice(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto handle = request.Pop<NpadDeviceHandle>();
|
auto handle{request.Pop<NpadDeviceHandle>()};
|
||||||
|
|
||||||
if (!handle.isRight)
|
if (!handle.isRight)
|
||||||
state.input->npad.at(handle.id).vibrationRight = NpadVibrationValue{};
|
state.input->npad.at(handle.id).vibrationRight = NpadVibrationValue{};
|
||||||
|
@ -9,7 +9,7 @@ namespace skyline::service::hid {
|
|||||||
IAppletResource::IAppletResource(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
IAppletResource::IAppletResource(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IAppletResource::GetSharedMemoryHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IAppletResource::GetSharedMemoryHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto handle = state.process->InsertItem<type::KSharedMemory>(state.input->kHid);
|
auto handle{state.process->InsertItem<type::KSharedMemory>(state.input->kHid)};
|
||||||
state.logger->Debug("HID Shared Memory Handle: 0x{:X}", handle);
|
state.logger->Debug("HID Shared Memory Handle: 0x{:X}", handle);
|
||||||
|
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
|
@ -26,7 +26,7 @@ namespace skyline::service::hid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IHidServer::SetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IHidServer::SetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto styleSet = request.Pop<NpadStyleSet>();
|
auto styleSet{request.Pop<NpadStyleSet>()};
|
||||||
std::lock_guard lock(state.input->npad.mutex);
|
std::lock_guard lock(state.input->npad.mutex);
|
||||||
state.input->npad.styles = styleSet;
|
state.input->npad.styles = styleSet;
|
||||||
state.input->npad.Update();
|
state.input->npad.Update();
|
||||||
@ -60,13 +60,13 @@ namespace skyline::service::hid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IHidServer::AcquireNpadStyleSetUpdateEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IHidServer::AcquireNpadStyleSetUpdateEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto id = request.Pop<NpadId>();
|
auto id{request.Pop<NpadId>()};
|
||||||
request.copyHandles.push_back(state.process->InsertItem(state.input->npad.at(id).updateEvent));
|
request.copyHandles.push_back(state.process->InsertItem(state.input->npad.at(id).updateEvent));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
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] {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case NpadId::Player1:
|
case NpadId::Player1:
|
||||||
@ -111,7 +111,7 @@ namespace skyline::service::hid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IHidServer::SetNpadJoyAssignmentModeSingleByDefault(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IHidServer::SetNpadJoyAssignmentModeSingleByDefault(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto id = request.Pop<NpadId>();
|
auto id{request.Pop<NpadId>()};
|
||||||
std::lock_guard lock(state.input->npad.mutex);
|
std::lock_guard lock(state.input->npad.mutex);
|
||||||
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Single);
|
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Single);
|
||||||
state.input->npad.Update();
|
state.input->npad.Update();
|
||||||
@ -119,7 +119,7 @@ namespace skyline::service::hid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IHidServer::SetNpadJoyAssignmentModeSingle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IHidServer::SetNpadJoyAssignmentModeSingle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto id = request.Pop<NpadId>();
|
auto id{request.Pop<NpadId>()};
|
||||||
std::lock_guard lock(state.input->npad.mutex);
|
std::lock_guard lock(state.input->npad.mutex);
|
||||||
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Single);
|
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Single);
|
||||||
state.input->npad.Update();
|
state.input->npad.Update();
|
||||||
@ -127,7 +127,7 @@ namespace skyline::service::hid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IHidServer::SetNpadJoyAssignmentModeDual(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IHidServer::SetNpadJoyAssignmentModeDual(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto id = request.Pop<NpadId>();
|
auto id{request.Pop<NpadId>()};
|
||||||
std::lock_guard lock(state.input->npad.mutex);
|
std::lock_guard lock(state.input->npad.mutex);
|
||||||
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Dual);
|
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Dual);
|
||||||
state.input->npad.Update();
|
state.input->npad.Update();
|
||||||
@ -146,15 +146,15 @@ namespace skyline::service::hid {
|
|||||||
auto values{request.inputBuf.at(1).cast<NpadVibrationValue>()};
|
auto values{request.inputBuf.at(1).cast<NpadVibrationValue>()};
|
||||||
|
|
||||||
for (size_t i{}; i < handles.size(); ++i) {
|
for (size_t i{}; i < handles.size(); ++i) {
|
||||||
const auto &handle = handles[i];
|
const auto &handle{handles[i]};
|
||||||
auto &device = state.input->npad.at(handle.id);
|
auto &device{state.input->npad.at(handle.id)};
|
||||||
if (device.type == handle.GetType()) {
|
if (device.type == handle.GetType()) {
|
||||||
if (i + 1 != handles.size() && handles[i + 1].id == handle.id && handles[i + 1].isRight && !handle.isRight) {
|
if (i + 1 != handles.size() && handles[i + 1].id == handle.id && handles[i + 1].isRight && !handle.isRight) {
|
||||||
state.logger->Debug("Vibration #{}&{} - Handle: 0x{:02X} (0b{:05b}), Vibration: {:.2f}@{:.2f}Hz, {:.2f}@{:.2f}Hz - {:.2f}@{:.2f}Hz, {:.2f}@{:.2f}Hz", i, i + 1, u8(handle.id), u8(handle.type), values[i].amplitudeLow, values[i].frequencyLow, values[i].amplitudeHigh, values[i].frequencyHigh, values[i + 1].amplitudeLow, values[i + 1].frequencyLow, values[i + 1].amplitudeHigh, values[i + 1].frequencyHigh);
|
state.logger->Debug("Vibration #{}&{} - Handle: 0x{:02X} (0b{:05b}), Vibration: {:.2f}@{:.2f}Hz, {:.2f}@{:.2f}Hz - {:.2f}@{:.2f}Hz, {:.2f}@{:.2f}Hz", i, i + 1, u8(handle.id), u8(handle.type), values[i].amplitudeLow, values[i].frequencyLow, values[i].amplitudeHigh, values[i].frequencyHigh, values[i + 1].amplitudeLow, values[i + 1].frequencyLow, values[i + 1].amplitudeHigh, values[i + 1].frequencyHigh);
|
||||||
device.Vibrate(values[i], values[i + 1]);
|
device.Vibrate(values[i], values[i + 1]);
|
||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
const auto &value = values[i];
|
const auto &value{values[i]};
|
||||||
state.logger->Debug("Vibration #{} - Handle: 0x{:02X} (0b{:05b}), Vibration: {:.2f}@{:.2f}Hz, {:.2f}@{:.2f}Hz", i, u8(handle.id), u8(handle.type), value.amplitudeLow, value.frequencyLow, value.amplitudeHigh, value.frequencyHigh);
|
state.logger->Debug("Vibration #{} - Handle: 0x{:02X} (0b{:05b}), Vibration: {:.2f}@{:.2f}Hz, {:.2f}@{:.2f}Hz", i, u8(handle.id), u8(handle.type), value.amplitudeLow, value.frequencyLow, value.amplitudeHigh, value.frequencyHigh);
|
||||||
device.Vibrate(handle.isRight, value);
|
device.Vibrate(handle.isRight, value);
|
||||||
}
|
}
|
||||||
|
@ -61,11 +61,11 @@ namespace skyline::service::hosbinder {
|
|||||||
nvdrv::Fence fence[4];
|
nvdrv::Fence fence[4];
|
||||||
} &data = in.Pop<Data>();
|
} &data = in.Pop<Data>();
|
||||||
|
|
||||||
auto buffer = queue.at(data.slot);
|
auto buffer{queue.at(data.slot)};
|
||||||
buffer->status = BufferStatus::Queued;
|
buffer->status = BufferStatus::Queued;
|
||||||
|
|
||||||
auto slot = data.slot;
|
auto slot{data.slot};
|
||||||
auto bufferEvent = state.gpu->bufferEvent;
|
auto bufferEvent{state.gpu->bufferEvent};
|
||||||
buffer->texture->releaseCallback = [this, slot, bufferEvent]() {
|
buffer->texture->releaseCallback = [this, slot, bufferEvent]() {
|
||||||
queue.at(slot)->status = BufferStatus::Free;
|
queue.at(slot)->status = BufferStatus::Free;
|
||||||
bufferEvent->Signal();
|
bufferEvent->Signal();
|
||||||
@ -116,12 +116,12 @@ namespace skyline::service::hosbinder {
|
|||||||
u32 _pad0_;
|
u32 _pad0_;
|
||||||
} &data = in.Pop<Data>();
|
} &data = in.Pop<Data>();
|
||||||
|
|
||||||
auto& gbpBuffer = in.Pop<GbpBuffer>();
|
auto& gbpBuffer{in.Pop<GbpBuffer>()};
|
||||||
|
|
||||||
std::shared_ptr<nvdrv::device::NvMap::NvMapObject> nvBuffer{};
|
std::shared_ptr<nvdrv::device::NvMap::NvMapObject> nvBuffer{};
|
||||||
|
|
||||||
auto driver = nvdrv::driver.lock();
|
auto driver{nvdrv::driver.lock()};
|
||||||
auto nvmap = driver->nvMap.lock();
|
auto nvmap{driver->nvMap.lock()};
|
||||||
|
|
||||||
if (gbpBuffer.nvmapHandle) {
|
if (gbpBuffer.nvmapHandle) {
|
||||||
nvBuffer = nvmap->handleTable.at(gbpBuffer.nvmapHandle);
|
nvBuffer = nvmap->handleTable.at(gbpBuffer.nvmapHandle);
|
||||||
@ -149,7 +149,7 @@ namespace skyline::service::hosbinder {
|
|||||||
throw exception("Unknown pixel format used for FB");
|
throw exception("Unknown pixel format used for FB");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto texture = std::make_shared<gpu::GuestTexture>(state, nvBuffer->address + gbpBuffer.offset, gpu::texture::Dimensions(gbpBuffer.width, gbpBuffer.height), format, gpu::texture::TileMode::Block, gpu::texture::TileConfig{.surfaceWidth = static_cast<u16>(gbpBuffer.stride), .blockHeight = static_cast<u8>(1U << gbpBuffer.blockHeightLog2), .blockDepth = 1});
|
auto texture{std::make_shared<gpu::GuestTexture>(state, nvBuffer->address + gbpBuffer.offset, gpu::texture::Dimensions(gbpBuffer.width, gbpBuffer.height), format, gpu::texture::TileMode::Block, gpu::texture::TileConfig{.surfaceWidth = static_cast<u16>(gbpBuffer.stride), .blockHeight = static_cast<u8>(1U << gbpBuffer.blockHeightLog2), .blockDepth = 1})};
|
||||||
|
|
||||||
queue[data.slot] = std::make_shared<Buffer>(gbpBuffer, texture->InitializePresentationTexture());
|
queue[data.slot] = std::make_shared<Buffer>(gbpBuffer, texture->InitializePresentationTexture());
|
||||||
state.gpu->bufferEvent->Signal();
|
state.gpu->bufferEvent->Signal();
|
||||||
|
@ -13,8 +13,8 @@ namespace skyline::service::hosbinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IHOSBinderDriver::TransactParcel(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IHOSBinderDriver::TransactParcel(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto layerId = request.Pop<u32>();
|
auto layerId{request.Pop<u32>()};
|
||||||
auto code = request.Pop<GraphicBufferProducer::TransactionCode>();
|
auto code{request.Pop<GraphicBufferProducer::TransactionCode>()};
|
||||||
|
|
||||||
Parcel in(request.inputBuf.at(0), state, true);
|
Parcel in(request.inputBuf.at(0), state, true);
|
||||||
Parcel out(state);
|
Parcel out(state);
|
||||||
@ -28,15 +28,15 @@ namespace skyline::service::hosbinder {
|
|||||||
|
|
||||||
Result IHOSBinderDriver::AdjustRefcount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IHOSBinderDriver::AdjustRefcount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
request.Skip<u32>();
|
request.Skip<u32>();
|
||||||
auto addVal = request.Pop<i32>();
|
auto addVal{request.Pop<i32>()};
|
||||||
auto type = request.Pop<i32>();
|
auto type{request.Pop<i32>()};
|
||||||
state.logger->Debug("Reference Change: {} {} reference", addVal, type ? "strong" : "weak");
|
state.logger->Debug("Reference Change: {} {} reference", addVal, type ? "strong" : "weak");
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IHOSBinderDriver::GetNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IHOSBinderDriver::GetNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
KHandle handle = state.process->InsertItem(state.gpu->bufferEvent);
|
KHandle handle{state.process->InsertItem(state.gpu->bufferEvent)};
|
||||||
state.logger->Debug("Display Buffer Event Handle: 0x{:X}", handle);
|
state.logger->Debug("Display Buffer Event Handle: 0x{:X}", handle);
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
|
|
||||||
|
@ -44,11 +44,11 @@ namespace skyline::service::lm {
|
|||||||
std::ostringstream logMessage;
|
std::ostringstream logMessage;
|
||||||
logMessage << "Guest log:";
|
logMessage << "Guest log:";
|
||||||
|
|
||||||
u64 offset = sizeof(Data);
|
u64 offset{sizeof(Data)};
|
||||||
while (offset < request.inputBuf[0].size()) {
|
while (offset < request.inputBuf[0].size()) {
|
||||||
auto fieldType = request.inputBuf[0].subspan(offset++).as<LogFieldType>();
|
auto fieldType{request.inputBuf[0].subspan(offset++).as<LogFieldType>()};
|
||||||
auto length = request.inputBuf[0].subspan(offset++).as<u8>();
|
auto length{request.inputBuf[0].subspan(offset++).as<u8>()};
|
||||||
auto object = request.inputBuf[0].subspan(offset, length);
|
auto object{request.inputBuf[0].subspan(offset, length)};
|
||||||
|
|
||||||
logMessage << " ";
|
logMessage << " ";
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ namespace skyline::service::nifm {
|
|||||||
IRequest::IRequest(const DeviceState &state, ServiceManager &manager) : event0(std::make_shared<type::KEvent>(state)), event1(std::make_shared<type::KEvent>(state)), BaseService(state, manager) {}
|
IRequest::IRequest(const DeviceState &state, ServiceManager &manager) : event0(std::make_shared<type::KEvent>(state)), event1(std::make_shared<type::KEvent>(state)), BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IRequest::GetRequestState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IRequest::GetRequestState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
constexpr u32 Unsubmitted = 1; //!< The request has not been submitted
|
constexpr u32 Unsubmitted{1}; //!< The request has not been submitted
|
||||||
response.Push<u32>(Unsubmitted);
|
response.Push<u32>(Unsubmitted);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -18,7 +18,7 @@ namespace skyline::service::nifm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IRequest::GetSystemEventReadableHandles(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IRequest::GetSystemEventReadableHandles(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto handle = state.process->InsertItem(event0);
|
auto handle{state.process->InsertItem(event0)};
|
||||||
state.logger->Debug("Request Event 0 Handle: 0x{:X}", handle);
|
state.logger->Debug("Request Event 0 Handle: 0x{:X}", handle);
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
|
|
||||||
|
@ -22,10 +22,10 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result INvDrvServices::Ioctl(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result INvDrvServices::Ioctl(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto fd = request.Pop<u32>();
|
auto fd{request.Pop<u32>()};
|
||||||
auto cmd = request.Pop<u32>();
|
auto cmd{request.Pop<u32>()};
|
||||||
|
|
||||||
auto device = driver->GetDevice(fd);
|
auto device{driver->GetDevice(fd)};
|
||||||
|
|
||||||
// Strip the permissions from the command leaving only the ID
|
// Strip the permissions from the command leaving only the ID
|
||||||
cmd &= 0xFFFF;
|
cmd &= 0xFFFF;
|
||||||
@ -52,7 +52,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<u32>()};
|
||||||
state.logger->Debug("Closing NVDRV device ({})", fd);
|
state.logger->Debug("Closing NVDRV device ({})", fd);
|
||||||
|
|
||||||
driver->CloseDevice(fd);
|
driver->CloseDevice(fd);
|
||||||
@ -67,14 +67,14 @@ 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<u32>()};
|
||||||
auto eventId = request.Pop<u32>();
|
auto eventId{request.Pop<u32>()};
|
||||||
|
|
||||||
auto device = driver->GetDevice(fd);
|
auto device{driver->GetDevice(fd)};
|
||||||
auto event = device->QueryEvent(eventId);
|
auto event{device->QueryEvent(eventId)};
|
||||||
|
|
||||||
if (event != nullptr) {
|
if (event != nullptr) {
|
||||||
auto handle = state.process->InsertItem<type::KEvent>(event);
|
auto handle{state.process->InsertItem<type::KEvent>(event)};
|
||||||
|
|
||||||
state.logger->Debug("QueryEvent: FD: {}, Event ID: {}, Handle: {}", fd, eventId, handle);
|
state.logger->Debug("QueryEvent: FD: {}, Event ID: {}, Handle: {}", fd, eventId, handle);
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
@ -93,10 +93,10 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result INvDrvServices::Ioctl2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result INvDrvServices::Ioctl2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto fd = request.Pop<u32>();
|
auto fd{request.Pop<u32>()};
|
||||||
auto cmd = request.Pop<u32>();
|
auto cmd{request.Pop<u32>()};
|
||||||
|
|
||||||
auto device = driver->GetDevice(fd);
|
auto device{driver->GetDevice(fd)};
|
||||||
|
|
||||||
// Strip the permissions from the command leaving only the ID
|
// Strip the permissions from the command leaving only the ID
|
||||||
cmd &= 0xFFFF;
|
cmd &= 0xFFFF;
|
||||||
@ -117,10 +117,10 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result INvDrvServices::Ioctl3(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result INvDrvServices::Ioctl3(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto fd = request.Pop<u32>();
|
auto fd{request.Pop<u32>()};
|
||||||
auto cmd = request.Pop<u32>();
|
auto cmd{request.Pop<u32>()};
|
||||||
|
|
||||||
auto device = driver->GetDevice(fd);
|
auto device{driver->GetDevice(fd)};
|
||||||
|
|
||||||
// Strip the permissions from the command leaving only the ID
|
// Strip the permissions from the command leaving only the ID
|
||||||
cmd &= 0xFFFF;
|
cmd &= 0xFFFF;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
namespace skyline::service::nvdrv::device {
|
namespace skyline::service::nvdrv::device {
|
||||||
const std::string &NvDevice::GetName() {
|
const std::string &NvDevice::GetName() {
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
auto mangledName = typeid(*this).name();
|
auto mangledName{typeid(*this).name()};
|
||||||
|
|
||||||
int status{};
|
int status{};
|
||||||
size_t length{};
|
size_t length{};
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#define NVDEVICE_DECL(...) \
|
#define NVDEVICE_DECL(...) \
|
||||||
NVDEVICE_DECL_AUTO(functions, frz::make_unordered_map({__VA_ARGS__})); \
|
NVDEVICE_DECL_AUTO(functions, frz::make_unordered_map({__VA_ARGS__})); \
|
||||||
std::pair<std::function<NvStatus(IoctlType, span<u8>, span<u8>)>, std::string_view> GetIoctlFunction(u32 id) { \
|
std::pair<std::function<NvStatus(IoctlType, span<u8>, span<u8>)>, std::string_view> GetIoctlFunction(u32 id) { \
|
||||||
auto& function = functions.at(id); \
|
auto& function{functions.at(id)}; \
|
||||||
return std::make_pair(std::bind(function.first, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), function.second); \
|
return std::make_pair(std::bind(function.first, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), function.second); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
};
|
};
|
||||||
} region = buffer.as<Data>();
|
} region = buffer.as<Data>();
|
||||||
|
|
||||||
u64 size = static_cast<u64>(region.pages) * static_cast<u64>(region.pageSize);
|
u64 size{static_cast<u64>(region.pages) * static_cast<u64>(region.pageSize)};
|
||||||
|
|
||||||
if (region.flags & 1)
|
if (region.flags & 1)
|
||||||
region.offset = state.gpu->memoryManager.ReserveFixed(region.offset, size);
|
region.offset = state.gpu->memoryManager.ReserveFixed(region.offset, size);
|
||||||
@ -61,12 +61,12 @@ namespace skyline::service::nvdrv::device {
|
|||||||
} &data = buffer.as<Data>();
|
} &data = buffer.as<Data>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto driver = nvdrv::driver.lock();
|
auto driver{nvdrv::driver.lock()};
|
||||||
auto nvmap = driver->nvMap.lock();
|
auto nvmap{driver->nvMap.lock()};
|
||||||
auto mapping = nvmap->handleTable.at(data.nvmapHandle);
|
auto mapping{nvmap->handleTable.at(data.nvmapHandle)};
|
||||||
|
|
||||||
u64 mapPhysicalAddress = data.bufferOffset + mapping->address;
|
u64 mapPhysicalAddress{data.bufferOffset + mapping->address};
|
||||||
u64 mapSize = data.mappingSize ? data.mappingSize : mapping->size;
|
u64 mapSize{data.mappingSize ? data.mappingSize : mapping->size};
|
||||||
|
|
||||||
if (data.flags & 1)
|
if (data.flags & 1)
|
||||||
data.offset = state.gpu->memoryManager.MapFixed(data.offset, mapPhysicalAddress, mapSize);
|
data.offset = state.gpu->memoryManager.MapFixed(data.offset, mapPhysicalAddress, mapSize);
|
||||||
@ -133,13 +133,13 @@ namespace skyline::service::nvdrv::device {
|
|||||||
auto entries{buffer.cast<Entry>()};
|
auto entries{buffer.cast<Entry>()};
|
||||||
for (auto entry : entries) {
|
for (auto entry : entries) {
|
||||||
try {
|
try {
|
||||||
auto driver = nvdrv::driver.lock();
|
auto driver{nvdrv::driver.lock()};
|
||||||
auto nvmap = driver->nvMap.lock();
|
auto nvmap{driver->nvMap.lock()};
|
||||||
auto mapping = nvmap->handleTable.at(entry.nvmapHandle);
|
auto mapping{nvmap->handleTable.at(entry.nvmapHandle)};
|
||||||
|
|
||||||
u64 mapAddress = static_cast<u64>(entry.gpuOffset) << MinAlignmentShift;
|
u64 mapAddress{static_cast<u64>(entry.gpuOffset) << MinAlignmentShift};
|
||||||
u64 mapPhysicalAddress = mapping->address + (static_cast<u64>(entry.mapOffset) << MinAlignmentShift);
|
u64 mapPhysicalAddress{mapping->address + (static_cast<u64>(entry.mapOffset) << MinAlignmentShift)};
|
||||||
u64 mapSize = static_cast<u64>(entry.pages) << MinAlignmentShift;
|
u64 mapSize{static_cast<u64>(entry.pages) << MinAlignmentShift};
|
||||||
|
|
||||||
state.gpu->memoryManager.MapFixed(mapAddress, mapPhysicalAddress, mapSize);
|
state.gpu->memoryManager.MapFixed(mapAddress, mapPhysicalAddress, mapSize);
|
||||||
} catch (const std::out_of_range &) {
|
} catch (const std::out_of_range &) {
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
namespace skyline::service::nvdrv::device {
|
namespace skyline::service::nvdrv::device {
|
||||||
NvHostChannel::NvHostChannel(const DeviceState &state) : smExceptionBreakpointIntReportEvent(std::make_shared<type::KEvent>(state)), smExceptionBreakpointPauseReportEvent(std::make_shared<type::KEvent>(state)), errorNotifierEvent(std::make_shared<type::KEvent>(state)), NvDevice(state) {
|
NvHostChannel::NvHostChannel(const DeviceState &state) : smExceptionBreakpointIntReportEvent(std::make_shared<type::KEvent>(state)), smExceptionBreakpointPauseReportEvent(std::make_shared<type::KEvent>(state)), errorNotifierEvent(std::make_shared<type::KEvent>(state)), NvDevice(state) {
|
||||||
auto driver = nvdrv::driver.lock();
|
auto driver{nvdrv::driver.lock()};
|
||||||
auto &hostSyncpoint = driver->hostSyncpoint;
|
auto &hostSyncpoint{driver->hostSyncpoint};
|
||||||
|
|
||||||
channelFence.id = hostSyncpoint.AllocateSyncpoint(false);
|
channelFence.id = hostSyncpoint.AllocateSyncpoint(false);
|
||||||
channelFence.UpdateValue(hostSyncpoint);
|
channelFence.UpdateValue(hostSyncpoint);
|
||||||
@ -43,8 +43,8 @@ namespace skyline::service::nvdrv::device {
|
|||||||
Fence fence; // InOut
|
Fence fence; // InOut
|
||||||
} &data = buffer.as<Data>();
|
} &data = buffer.as<Data>();
|
||||||
|
|
||||||
auto driver = nvdrv::driver.lock();
|
auto driver{nvdrv::driver.lock()};
|
||||||
auto &hostSyncpoint = driver->hostSyncpoint;
|
auto &hostSyncpoint{driver->hostSyncpoint};
|
||||||
|
|
||||||
if (data.flags.fenceWait) {
|
if (data.flags.fenceWait) {
|
||||||
if (data.flags.incrementWithValue)
|
if (data.flags.incrementWithValue)
|
||||||
@ -58,7 +58,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
|
|
||||||
data.fence.id = channelFence.id;
|
data.fence.id = channelFence.id;
|
||||||
|
|
||||||
u32 increment = (data.flags.fenceIncrement ? 2 : 0) + (data.flags.incrementWithValue ? data.fence.value : 0);
|
u32 increment{(data.flags.fenceIncrement ? 2 : 0) + (data.flags.incrementWithValue ? data.fence.value : 0)};
|
||||||
data.fence.value = hostSyncpoint.IncrementSyncpointMaxExt(data.fence.id, increment);
|
data.fence.value = hostSyncpoint.IncrementSyncpointMaxExt(data.fence.id, increment);
|
||||||
|
|
||||||
if (data.flags.fenceIncrement)
|
if (data.flags.fenceIncrement)
|
||||||
@ -106,7 +106,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
u32 reserved[3]; // In
|
u32 reserved[3]; // In
|
||||||
} &data = buffer.as<Data>();
|
} &data = buffer.as<Data>();
|
||||||
|
|
||||||
auto driver = nvdrv::driver.lock();
|
auto driver{nvdrv::driver.lock()};
|
||||||
channelFence.UpdateValue(driver->hostSyncpoint);
|
channelFence.UpdateValue(driver->hostSyncpoint);
|
||||||
data.fence = channelFence;
|
data.fence = channelFence;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
NvHostEvent::NvHostEvent(const DeviceState &state) : event(std::make_shared<type::KEvent>(state)) {}
|
NvHostEvent::NvHostEvent(const DeviceState &state) : event(std::make_shared<type::KEvent>(state)) {}
|
||||||
|
|
||||||
void NvHostEvent::Signal() {
|
void NvHostEvent::Signal() {
|
||||||
auto oldState = state;
|
auto oldState{state};
|
||||||
state = State::Signaling;
|
state = State::Signaling;
|
||||||
|
|
||||||
// This is to ensure that the HOS event isn't signalled when the nvhost event is cancelled
|
// This is to ensure that the HOS event isn't signalled when the nvhost event is cancelled
|
||||||
@ -44,7 +44,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
|
|
||||||
for (u32 i{}; i < constant::NvHostEventCount; i++) {
|
for (u32 i{}; i < constant::NvHostEventCount; i++) {
|
||||||
if (events[i]) {
|
if (events[i]) {
|
||||||
const auto &event = *events[i];
|
const auto &event{*events[i]};
|
||||||
|
|
||||||
if (event.state == NvHostEvent::State::Cancelled || event.state == NvHostEvent::State::Available || event.state == NvHostEvent::State::Signaled) {
|
if (event.state == NvHostEvent::State::Cancelled || event.state == NvHostEvent::State::Available || event.state == NvHostEvent::State::Signaled) {
|
||||||
eventIndex = i;
|
eventIndex = i;
|
||||||
@ -84,8 +84,8 @@ namespace skyline::service::nvdrv::device {
|
|||||||
if (data.timeout == 0)
|
if (data.timeout == 0)
|
||||||
return NvStatus::Timeout;
|
return NvStatus::Timeout;
|
||||||
|
|
||||||
auto driver = nvdrv::driver.lock();
|
auto driver{nvdrv::driver.lock()};
|
||||||
auto &hostSyncpoint = driver->hostSyncpoint;
|
auto &hostSyncpoint{driver->hostSyncpoint};
|
||||||
|
|
||||||
// Check if the syncpoint has already expired using the last known values
|
// Check if the syncpoint has already expired using the last known values
|
||||||
if (hostSyncpoint.HasSyncpointExpired(data.fence.id, data.fence.value)) {
|
if (hostSyncpoint.HasSyncpointExpired(data.fence.id, data.fence.value)) {
|
||||||
@ -94,7 +94,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sync the syncpoint with the GPU then check again
|
// Sync the syncpoint with the GPU then check again
|
||||||
auto minVal = hostSyncpoint.UpdateMin(data.fence.id);
|
auto minVal{hostSyncpoint.UpdateMin(data.fence.id)};
|
||||||
if (hostSyncpoint.HasSyncpointExpired(data.fence.id, data.fence.value)) {
|
if (hostSyncpoint.HasSyncpointExpired(data.fence.id, data.fence.value)) {
|
||||||
data.value.val = minVal;
|
data.value.val = minVal;
|
||||||
return NvStatus::Success;
|
return NvStatus::Success;
|
||||||
@ -112,7 +112,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
userEventId = FindFreeEvent(data.fence.id);
|
userEventId = FindFreeEvent(data.fence.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& event = *events.at(userEventId);
|
auto& event{*events.at(userEventId)};
|
||||||
if (event.state == NvHostEvent::State::Cancelled || event.state == NvHostEvent::State::Available || event.state == NvHostEvent::State::Signaled) {
|
if (event.state == NvHostEvent::State::Cancelled || event.state == NvHostEvent::State::Available || event.state == NvHostEvent::State::Signaled) {
|
||||||
state.logger->Debug("Now waiting on nvhost event: {} with fence: {}", userEventId, data.fence.id);
|
state.logger->Debug("Now waiting on nvhost event: {} with fence: {}", userEventId, data.fence.id);
|
||||||
event.Wait(state.gpu, data.fence);
|
event.Wait(state.gpu, data.fence);
|
||||||
@ -145,7 +145,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
if (userEventId >= constant::NvHostEventCount || !events.at(userEventId))
|
if (userEventId >= constant::NvHostEventCount || !events.at(userEventId))
|
||||||
return NvStatus::BadValue;
|
return NvStatus::BadValue;
|
||||||
|
|
||||||
auto &event = *events.at(userEventId);
|
auto &event{*events.at(userEventId)};
|
||||||
|
|
||||||
if (event.state == NvHostEvent::State::Waiting) {
|
if (event.state == NvHostEvent::State::Waiting) {
|
||||||
event.state = NvHostEvent::State::Cancelling;
|
event.state = NvHostEvent::State::Cancelling;
|
||||||
@ -155,8 +155,8 @@ namespace skyline::service::nvdrv::device {
|
|||||||
|
|
||||||
event.state = NvHostEvent::State::Cancelled;
|
event.state = NvHostEvent::State::Cancelled;
|
||||||
|
|
||||||
auto driver = nvdrv::driver.lock();
|
auto driver{nvdrv::driver.lock()};
|
||||||
auto &hostSyncpoint = driver->hostSyncpoint;
|
auto &hostSyncpoint{driver->hostSyncpoint};
|
||||||
hostSyncpoint.UpdateMin(event.fence.id);
|
hostSyncpoint.UpdateMin(event.fence.id);
|
||||||
|
|
||||||
return NvStatus::Success;
|
return NvStatus::Success;
|
||||||
@ -174,7 +174,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
auto userEventId{buffer.as<u32>()};
|
auto userEventId{buffer.as<u32>()};
|
||||||
state.logger->Debug("Registering nvhost event: {}", userEventId);
|
state.logger->Debug("Registering nvhost event: {}", userEventId);
|
||||||
|
|
||||||
auto &event = events.at(userEventId);
|
auto &event{events.at(userEventId)};
|
||||||
if (event)
|
if (event)
|
||||||
throw exception("Recreating events is unimplemented");
|
throw exception("Recreating events is unimplemented");
|
||||||
event = NvHostEvent(state);
|
event = NvHostEvent(state);
|
||||||
@ -184,7 +184,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
|
|
||||||
std::shared_ptr<type::KEvent> NvHostCtrl::QueryEvent(u32 eventId) {
|
std::shared_ptr<type::KEvent> NvHostCtrl::QueryEvent(u32 eventId) {
|
||||||
EventValue eventValue{.val = eventId};
|
EventValue eventValue{.val = eventId};
|
||||||
const auto &event = events.at(eventValue.nonAsync ? eventValue.eventSlotNonAsync : eventValue.eventSlotAsync);
|
const auto &event{events.at(eventValue.nonAsync ? eventValue.eventSlotNonAsync : eventValue.eventSlotAsync)};
|
||||||
|
|
||||||
if (event && event->fence.id == (eventValue.nonAsync ? eventValue.syncpointIdNonAsync : eventValue.syncpointIdAsync))
|
if (event && event->fence.id == (eventValue.nonAsync ? eventValue.syncpointIdNonAsync : eventValue.syncpointIdAsync))
|
||||||
return event->event;
|
return event->event;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr u32 NvHostEventCount = 64; //!< The maximum number of nvhost events
|
constexpr u32 NvHostEventCount{64}; //!< The maximum number of nvhost events
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace service::nvdrv::device {
|
namespace service::nvdrv::device {
|
||||||
|
@ -26,7 +26,7 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 NvHostSyncpoint::FindFreeSyncpoint() {
|
u32 NvHostSyncpoint::FindFreeSyncpoint() {
|
||||||
for (u32 i = 0; i < constant::MaxHwSyncpointCount; i++)
|
for (u32 i{}; i < constant::MaxHwSyncpointCount; i++)
|
||||||
if (!syncpoints[i].reserved)
|
if (!syncpoints[i].reserved)
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ namespace skyline::service::nvdrv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool NvHostSyncpoint::HasSyncpointExpired(u32 id, u32 threshold) {
|
bool NvHostSyncpoint::HasSyncpointExpired(u32 id, u32 threshold) {
|
||||||
const SyncpointInfo &syncpoint = syncpoints.at(id);
|
const SyncpointInfo &syncpoint{syncpoints.at(id)};
|
||||||
|
|
||||||
if (!syncpoint.reserved)
|
if (!syncpoint.reserved)
|
||||||
throw exception("Cannot check the expiry status of an unreserved syncpoint!");
|
throw exception("Cannot check the expiry status of an unreserved syncpoint!");
|
||||||
|
@ -51,7 +51,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
} &data = buffer.as<Data>();
|
} &data = buffer.as<Data>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto &object = handleTable.at(data.handle);
|
auto &object{handleTable.at(data.handle)};
|
||||||
object->heapMask = data.heapMask;
|
object->heapMask = data.heapMask;
|
||||||
object->flags = data.flags;
|
object->flags = data.flags;
|
||||||
object->align = data.align;
|
object->align = data.align;
|
||||||
@ -77,7 +77,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
} &data = buffer.as<Data>();
|
} &data = buffer.as<Data>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const auto &object = handleTable.at(data.handle);
|
const auto &object{handleTable.at(data.handle)};
|
||||||
if (object.use_count() > 1) {
|
if (object.use_count() > 1) {
|
||||||
data.address = static_cast<u32>(object->address);
|
data.address = static_cast<u32>(object->address);
|
||||||
data.flags = 0x0;
|
data.flags = 0x0;
|
||||||
@ -106,7 +106,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
} &data = buffer.as<Data>();
|
} &data = buffer.as<Data>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto &object = handleTable.at(data.handle);
|
auto &object{handleTable.at(data.handle)};
|
||||||
|
|
||||||
switch (data.parameter) {
|
switch (data.parameter) {
|
||||||
case Parameter::Size:
|
case Parameter::Size:
|
||||||
|
@ -39,7 +39,7 @@ namespace skyline::service::nvdrv {
|
|||||||
|
|
||||||
std::shared_ptr<device::NvDevice> Driver::GetDevice(u32 fd) {
|
std::shared_ptr<device::NvDevice> Driver::GetDevice(u32 fd) {
|
||||||
try {
|
try {
|
||||||
auto item = devices.at(fd);
|
auto item{devices.at(fd)};
|
||||||
if (!item)
|
if (!item)
|
||||||
throw exception("GetDevice was called with a closed file descriptor: 0x{:X}", fd);
|
throw exception("GetDevice was called with a closed file descriptor: 0x{:X}", fd);
|
||||||
return item;
|
return item;
|
||||||
@ -50,7 +50,7 @@ namespace skyline::service::nvdrv {
|
|||||||
|
|
||||||
void Driver::CloseDevice(u32 fd) {
|
void Driver::CloseDevice(u32 fd) {
|
||||||
try {
|
try {
|
||||||
auto &device = devices.at(fd);
|
auto &device{devices.at(fd)};
|
||||||
device.reset();
|
device.reset();
|
||||||
} catch (const std::out_of_range &) {
|
} catch (const std::out_of_range &) {
|
||||||
state.logger->Warn("Trying to close non-existent FD");
|
state.logger->Warn("Trying to close non-existent FD");
|
||||||
|
@ -30,11 +30,11 @@ namespace skyline::service::pl {
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
IPlatformServiceManager::IPlatformServiceManager(const DeviceState &state, ServiceManager &manager) : fontSharedMem(std::make_shared<kernel::type::KSharedMemory>(state, NULL, constant::FontSharedMemSize, memory::Permission{true, false, false})), BaseService(state, manager) {
|
IPlatformServiceManager::IPlatformServiceManager(const DeviceState &state, ServiceManager &manager) : fontSharedMem(std::make_shared<kernel::type::KSharedMemory>(state, NULL, constant::FontSharedMemSize, memory::Permission{true, false, false})), BaseService(state, manager) {
|
||||||
constexpr u32 SharedFontResult = 0x7F9A0218; //!< This is the decrypted magic for a single font in the shared font data
|
constexpr u32 SharedFontResult{0x7F9A0218}; //!< This is the decrypted magic for a single font in the shared font data
|
||||||
constexpr u32 SharedFontMagic = 0x36F81A1E; //!< This is the encrypted magic for a single font in the shared font data
|
constexpr u32 SharedFontMagic{0x36F81A1E}; //!< This is the encrypted magic for a single font in the shared font data
|
||||||
constexpr u32 SharedFontKey = SharedFontMagic ^SharedFontResult; //!< This is the XOR key for encrypting the font size
|
constexpr u32 SharedFontKey{SharedFontMagic ^SharedFontResult}; //!< This is the XOR key for encrypting the font size
|
||||||
|
|
||||||
auto pointer = reinterpret_cast<u32 *>(fontSharedMem->kernel.address);
|
auto pointer{reinterpret_cast<u32 *>(fontSharedMem->kernel.address)};
|
||||||
for (auto &font : fontTable) {
|
for (auto &font : fontTable) {
|
||||||
*pointer++ = SharedFontResult;
|
*pointer++ = SharedFontResult;
|
||||||
*pointer++ = font.length ^ SharedFontKey;
|
*pointer++ = font.length ^ SharedFontKey;
|
||||||
@ -46,28 +46,25 @@ namespace skyline::service::pl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result IPlatformServiceManager::GetLoadState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IPlatformServiceManager::GetLoadState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
constexpr u32 FontLoaded = 1; //!< This is returned to show that all fonts have been loaded into memory
|
constexpr u32 FontLoaded{1}; //!< This is returned to show that all fonts have been loaded into memory
|
||||||
|
|
||||||
response.Push(FontLoaded);
|
response.Push(FontLoaded);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IPlatformServiceManager::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IPlatformServiceManager::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto fontId = request.Pop<u32>();
|
auto fontId{request.Pop<u32>()};
|
||||||
|
|
||||||
response.Push<u32>(fontTable.at(fontId).length);
|
response.Push<u32>(fontTable.at(fontId).length);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IPlatformServiceManager::GetSharedMemoryAddressOffset(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IPlatformServiceManager::GetSharedMemoryAddressOffset(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto fontId = request.Pop<u32>();
|
auto fontId{request.Pop<u32>()};
|
||||||
|
|
||||||
response.Push<u32>(fontTable.at(fontId).offset);
|
response.Push<u32>(fontTable.at(fontId).offset);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IPlatformServiceManager::GetSharedMemoryNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IPlatformServiceManager::GetSharedMemoryNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto handle = state.process->InsertItem<type::KSharedMemory>(fontSharedMem);
|
auto handle{state.process->InsertItem<type::KSharedMemory>(fontSharedMem)};
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr u32 FontSharedMemSize = 0x1100000; //!< This is the total size of the font shared memory
|
constexpr u32 FontSharedMemSize{0x1100000}; //!< This is the total size of the font shared memory
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace service::pl {
|
namespace service::pl {
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -40,7 +40,7 @@ namespace skyline::service {
|
|||||||
ServiceManager::ServiceManager(const DeviceState &state) : state(state), smUserInterface(std::make_shared<sm::IUserInterface>(state, *this)) {}
|
ServiceManager::ServiceManager(const DeviceState &state) : state(state), smUserInterface(std::make_shared<sm::IUserInterface>(state, *this)) {}
|
||||||
|
|
||||||
std::shared_ptr<BaseService> ServiceManager::CreateService(ServiceName name) {
|
std::shared_ptr<BaseService> ServiceManager::CreateService(ServiceName name) {
|
||||||
auto serviceIter = serviceMap.find(name);
|
auto serviceIter{serviceMap.find(name)};
|
||||||
if (serviceIter != serviceMap.end())
|
if (serviceIter != serviceMap.end())
|
||||||
return (*serviceIter).second;
|
return (*serviceIter).second;
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ namespace skyline::service {
|
|||||||
|
|
||||||
std::shared_ptr<BaseService> ServiceManager::NewService(ServiceName name, type::KSession &session, ipc::IpcResponse &response) {
|
std::shared_ptr<BaseService> ServiceManager::NewService(ServiceName name, type::KSession &session, ipc::IpcResponse &response) {
|
||||||
std::lock_guard serviceGuard(mutex);
|
std::lock_guard serviceGuard(mutex);
|
||||||
auto serviceObject = CreateService(name);
|
auto serviceObject{CreateService(name)};
|
||||||
KHandle handle{};
|
KHandle handle{};
|
||||||
if (session.isDomain) {
|
if (session.isDomain) {
|
||||||
session.domainTable[++session.handleIndex] = serviceObject;
|
session.domainTable[++session.handleIndex] = serviceObject;
|
||||||
@ -118,7 +118,7 @@ namespace skyline::service {
|
|||||||
|
|
||||||
void ServiceManager::CloseSession(KHandle handle) {
|
void ServiceManager::CloseSession(KHandle handle) {
|
||||||
std::lock_guard serviceGuard(mutex);
|
std::lock_guard serviceGuard(mutex);
|
||||||
auto session = state.process->GetHandle<type::KSession>(handle);
|
auto session{state.process->GetHandle<type::KSession>(handle)};
|
||||||
if (session->serviceStatus == type::KSession::ServiceStatus::Open) {
|
if (session->serviceStatus == type::KSession::ServiceStatus::Open) {
|
||||||
if (session->isDomain) {
|
if (session->isDomain) {
|
||||||
for (const auto &domainEntry : session->domainTable)
|
for (const auto &domainEntry : session->domainTable)
|
||||||
@ -135,7 +135,7 @@ namespace skyline::service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServiceManager::SyncRequestHandler(KHandle handle) {
|
void ServiceManager::SyncRequestHandler(KHandle handle) {
|
||||||
auto session = state.process->GetHandle<type::KSession>(handle);
|
auto session{state.process->GetHandle<type::KSession>(handle)};
|
||||||
state.logger->Debug("----Start----");
|
state.logger->Debug("----Start----");
|
||||||
state.logger->Debug("Handle is 0x{:X}", handle);
|
state.logger->Debug("Handle is 0x{:X}", handle);
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ namespace skyline::service {
|
|||||||
case ipc::CommandType::RequestWithContext:
|
case ipc::CommandType::RequestWithContext:
|
||||||
if (session->isDomain) {
|
if (session->isDomain) {
|
||||||
try {
|
try {
|
||||||
auto service = session->domainTable.at(request.domain->objectId);
|
auto service{session->domainTable.at(request.domain->objectId)};
|
||||||
switch (static_cast<ipc::DomainCommand>(request.domain->command)) {
|
switch (static_cast<ipc::DomainCommand>(request.domain->command)) {
|
||||||
case ipc::DomainCommand::SendMessage:
|
case ipc::DomainCommand::SendMessage:
|
||||||
response.errorCode = service->HandleRequest(*session, request, response);
|
response.errorCode = service->HandleRequest(*session, request, response);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user