diff --git a/app/src/main/cpp/emu_jni.cpp b/app/src/main/cpp/emu_jni.cpp index 84451b69..a6addcb7 100644 --- a/app/src/main/cpp/emu_jni.cpp +++ b/app/src/main/cpp/emu_jni.cpp @@ -139,9 +139,8 @@ extern "C" JNIEXPORT void JNICALL Java_emu_skyline_EmulationActivity_setTouchSta auto input = inputWeak.lock(); jboolean isCopy{false}; - std::span points(reinterpret_cast(env->GetIntArrayElements(pointsJni, &isCopy)), env->GetArrayLength(pointsJni) / (sizeof(Point) / sizeof(jint))); + skyline::span points(reinterpret_cast(env->GetIntArrayElements(pointsJni, &isCopy)), env->GetArrayLength(pointsJni) / (sizeof(Point) / sizeof(jint))); input->touch.SetState(points); - env->ReleaseIntArrayElements(pointsJni, reinterpret_cast(points.data()), JNI_ABORT); } catch (const std::bad_weak_ptr &) { // We don't mind if we miss axis updates while input hasn't been initialized diff --git a/app/src/main/cpp/skyline/audio/adpcm_decoder.cpp b/app/src/main/cpp/skyline/audio/adpcm_decoder.cpp index 5289fde8..dcd050e2 100644 --- a/app/src/main/cpp/skyline/audio/adpcm_decoder.cpp +++ b/app/src/main/cpp/skyline/audio/adpcm_decoder.cpp @@ -9,7 +9,7 @@ namespace skyline::audio { AdpcmDecoder::AdpcmDecoder(const std::vector> &coefficients) : coefficients(coefficients) {} - std::vector AdpcmDecoder::Decode(std::span adpcmData) { + std::vector AdpcmDecoder::Decode(span adpcmData) { constexpr size_t BytesPerFrame{0x8}; constexpr size_t SamplesPerFrame{0xE}; diff --git a/app/src/main/cpp/skyline/audio/adpcm_decoder.h b/app/src/main/cpp/skyline/audio/adpcm_decoder.h index cf0fa40e..ee83fcb6 100644 --- a/app/src/main/cpp/skyline/audio/adpcm_decoder.h +++ b/app/src/main/cpp/skyline/audio/adpcm_decoder.h @@ -37,6 +37,6 @@ namespace skyline::audio { * @param adpcmData A buffer containing the raw ADPCM data * @return A buffer containing decoded single channel I16 PCM data */ - std::vector Decode(std::span adpcmData); + std::vector Decode(span adpcmData); }; } diff --git a/app/src/main/cpp/skyline/audio/circular_buffer.h b/app/src/main/cpp/skyline/audio/circular_buffer.h index 28d31c88..1b1d6ec2 100644 --- a/app/src/main/cpp/skyline/audio/circular_buffer.h +++ b/app/src/main/cpp/skyline/audio/circular_buffer.h @@ -146,7 +146,7 @@ namespace skyline::audio { * @brief This appends data from a span to the buffer * @param data A span containing the data to be appended */ - inline void Append(std::span data) { + inline void Append(span data) { Append(data.data(), data.size()); } }; diff --git a/app/src/main/cpp/skyline/audio/resampler.cpp b/app/src/main/cpp/skyline/audio/resampler.cpp index ed371da0..745ff1cf 100644 --- a/app/src/main/cpp/skyline/audio/resampler.cpp +++ b/app/src/main/cpp/skyline/audio/resampler.cpp @@ -121,7 +121,7 @@ namespace skyline::audio { {-42, 3751, 26253, 2811}, {-38, 3608, 26270, 2936}, {-34, 3467, 26281, 3064}, {-32, 3329, 26287, 3195}}}; // @fmt:on - std::vector Resampler::ResampleBuffer(std::span inputBuffer, double ratio, u8 channelCount) { + std::vector Resampler::ResampleBuffer(span inputBuffer, double ratio, u8 channelCount) { auto step{static_cast(ratio * 0x8000)}; auto outputSize{static_cast(inputBuffer.size() / ratio)}; std::vector outputBuffer(outputSize); diff --git a/app/src/main/cpp/skyline/audio/resampler.h b/app/src/main/cpp/skyline/audio/resampler.h index 2a6961ba..8edd09d6 100644 --- a/app/src/main/cpp/skyline/audio/resampler.h +++ b/app/src/main/cpp/skyline/audio/resampler.h @@ -21,6 +21,6 @@ namespace skyline::audio { * @param ratio The conversion ratio needed * @param channelCount The amount of channels the buffer contains */ - std::vector ResampleBuffer(std::span inputBuffer, double ratio, u8 channelCount); + std::vector ResampleBuffer(span inputBuffer, double ratio, u8 channelCount); }; } diff --git a/app/src/main/cpp/skyline/audio/track.cpp b/app/src/main/cpp/skyline/audio/track.cpp index b9a6567d..8dda92c8 100644 --- a/app/src/main/cpp/skyline/audio/track.cpp +++ b/app/src/main/cpp/skyline/audio/track.cpp @@ -44,7 +44,7 @@ namespace skyline::audio { return bufferIds; } - void AudioTrack::AppendBuffer(u64 tag, std::span buffer) { + void AudioTrack::AppendBuffer(u64 tag, span buffer) { BufferIdentifier identifier{ .released = false, .tag = tag, diff --git a/app/src/main/cpp/skyline/audio/track.h b/app/src/main/cpp/skyline/audio/track.h index 95187457..832242dc 100644 --- a/app/src/main/cpp/skyline/audio/track.h +++ b/app/src/main/cpp/skyline/audio/track.h @@ -66,7 +66,7 @@ namespace skyline::audio { * @param tag The tag of the buffer * @param buffer A span containing the source sample buffer */ - void AppendBuffer(u64 tag, std::span buffer = {}); + void AppendBuffer(u64 tag, span buffer = {}); /** * @brief Checks if any buffers have been released and calls the appropriate callback for them diff --git a/app/src/main/cpp/skyline/common.h b/app/src/main/cpp/skyline/common.h index 6ce0e4b0..c345e959 100644 --- a/app/src/main/cpp/skyline/common.h +++ b/app/src/main/cpp/skyline/common.h @@ -105,13 +105,7 @@ namespace skyline { } /** - * @brief Aligns up a value to a multiple of two - * @tparam Type The type of the values - * @param value The value to round up - * @param multiple The multiple to round up to (Should be a multiple of 2) - * @tparam TypeVal The type of the value - * @tparam TypeMul The type of the multiple - * @return The aligned value + * @return The value aligned up to the next multiple */ template constexpr inline TypeVal AlignUp(TypeVal value, TypeMul multiple) { @@ -120,12 +114,7 @@ namespace skyline { } /** - * @brief Aligns down a value to a multiple of two - * @param value The value to round down - * @param multiple The multiple to round down to (Should be a multiple of 2) - * @tparam TypeVal The type of the value - * @tparam TypeMul The type of the multiple - * @return The aligned value + * @return The value aligned down to the previous multiple */ template constexpr inline TypeVal AlignDown(TypeVal value, TypeMul multiple) { @@ -133,10 +122,7 @@ namespace skyline { } /** - * @param value The value to check for alignment - * @param multiple The multiple to check alignment with * @return If the address is aligned with the multiple - * @note The multiple must be divisible by 2 */ template constexpr inline bool IsAligned(TypeVal value, TypeMul multiple) { @@ -147,7 +133,6 @@ namespace skyline { } /** - * @param value The value to check for alignment * @return If the value is page aligned */ constexpr inline bool PageAligned(u64 value) { @@ -155,7 +140,6 @@ namespace skyline { } /** - * @param value The value to check for alignment * @return If the value is word aligned */ constexpr inline bool WordAligned(u64 value) { @@ -201,25 +185,118 @@ namespace skyline { return result; } + /** + * @brief A compile-time hash function as std::hash isn't constexpr + */ constexpr std::size_t Hash(std::string_view view) { return frz::elsa{}(frz::string(view.data(), view.size()), 0); } - - template - constexpr Out &As(std::span span) { - if (IsAligned(span.size_bytes(), sizeof(Out))) - return *reinterpret_cast(span.data()); - throw exception("Span size not aligned with Out type size (0x{:X}/0x{:X})", span.size_bytes(), sizeof(Out)); - } - - template - constexpr std::span AsSpan(std::span span) { - if (IsAligned(span.size_bytes(), sizeof(Out))) - return std::span(reinterpret_cast(span.data()), span.size_bytes() / sizeof(Out)); - throw exception("Span size not aligned with Out type size (0x{:X}/0x{:X})", span.size_bytes(), sizeof(Out)); - } } + /** + * @brief A custom wrapper over span that adds several useful methods to it + * @note This class is completely transparent, it implicitly converts from and to span + */ + template + class span : public std::span { + public: + using std::span::span; + using std::span::operator=; + + typedef typename std::span::element_type elementType; + typedef typename std::span::index_type indexType; + + constexpr span(const std::span &spn) : std::span(spn) {} + + /** + * @brief We want to support implicitly casting from std::string_view -> span as it is just a specialization of a data view which span is a generic form of, the opposite doesn't hold true as not all data held by a span is string data therefore the conversion isn't implicit there + */ + template + constexpr span(const std::basic_string_view &string) : std::span(const_cast(string.data()), string.size()) {} + + template + constexpr Out &as() { + if (span::size_bytes() >= sizeof(Out)) + return *reinterpret_cast(span::data()); + throw exception("Span size is less than Out type size (0x{:X}/0x{:X})", span::size_bytes(), sizeof(Out)); + } + + constexpr std::string_view as_string(indexType length = 0) { + return std::string_view(reinterpret_cast(span::data()), length ? length : span::size_bytes()); + } + + template + constexpr span cast() { + if (util::IsAligned(span::size_bytes(), sizeof(Out))) + return span(reinterpret_cast(span::data()), span::size_bytes() / sizeof(Out)); + throw exception("Span size not aligned with Out type size (0x{:X}/0x{:X})", span::size_bytes(), sizeof(Out)); + } + + /** + * @brief Copies data from the supplied span into this one + * @param amount The amount of elements that need to be copied (in terms of the supplied span), 0 will try to copy the entirety of the other span + */ + template + constexpr void copy_from(const span spn, indexType amount = 0) { + auto size{amount ? amount * sizeof(In) : spn.size_bytes()}; + if (span::size_bytes() < size) + throw exception("Data being copied is larger than this span"); + std::memmove(span::data(), spn.data(), size); + } + + /** + * @brief Implicit type conversion for copy_from, this allows passing in std::vector/std::array in directly is automatically passed by reference which is important for any containers + */ + template + constexpr void copy_from(const In &in, indexType amount = 0) { + copy_from(span::type>(in), amount); + } + + /** Base Class Functions that return an instance of it, we upcast them **/ + template + constexpr span first() const noexcept { + return std::span::template first(); + } + + template + constexpr span last() const noexcept { + return std::span::template last(); + } + + constexpr span first(indexType count) const noexcept { + return std::span::first(count); + } + + constexpr span last(indexType count) const noexcept { + return std::span::last(count); + } + + template + constexpr auto subspan() const noexcept -> span { + return std::span::template subspan(); + } + + constexpr span subspan(indexType offset, indexType count = std::dynamic_extent) const noexcept { + return std::span::subspan(offset, count); + } + }; + + /** + * @brief Deduction guides required for arguments to span, CTAD will fail for iterators, arrays and containers without this + */ + template + span(It, End) -> span::value_type, Extent>; + template + span(T (&)[Size]) -> span; + template + span(std::array &) -> span; + template + span(const std::array &) -> span; + template + span(Container &) -> span; + template + span(const Container &) -> span; + /** * @brief The Mutex class is a wrapper around an atomic bool used for synchronization */ diff --git a/app/src/main/cpp/skyline/crypto/aes_cipher.cpp b/app/src/main/cpp/skyline/crypto/aes_cipher.cpp index deba988d..33806ec2 100644 --- a/app/src/main/cpp/skyline/crypto/aes_cipher.cpp +++ b/app/src/main/cpp/skyline/crypto/aes_cipher.cpp @@ -4,7 +4,7 @@ #include "aes_cipher.h" namespace skyline::crypto { - AesCipher::AesCipher(std::span key, mbedtls_cipher_type_t type) { + AesCipher::AesCipher(span key, mbedtls_cipher_type_t type) { mbedtls_cipher_init(&decryptContext); if (mbedtls_cipher_setup(&decryptContext, mbedtls_cipher_info_from_type(type)) != 0) throw exception("Failed to setup decryption context"); diff --git a/app/src/main/cpp/skyline/crypto/aes_cipher.h b/app/src/main/cpp/skyline/crypto/aes_cipher.h index 3b75d1f1..d7881aa5 100644 --- a/app/src/main/cpp/skyline/crypto/aes_cipher.h +++ b/app/src/main/cpp/skyline/crypto/aes_cipher.h @@ -37,7 +37,7 @@ namespace skyline::crypto { } public: - AesCipher(std::span key, mbedtls_cipher_type_t type); + AesCipher(span key, mbedtls_cipher_type_t type); ~AesCipher(); @@ -54,7 +54,7 @@ namespace skyline::crypto { /** * @brief Decrypts data and writes back to it */ - inline void Decrypt(std::span data) { + inline void Decrypt(span data) { Decrypt(data.data(), data.data(), data.size()); } @@ -66,7 +66,7 @@ namespace skyline::crypto { /** * @brief Decrypts data with XTS and writes back to it */ - inline void XtsDecrypt(std::span data, size_t sector, size_t sectorSize) { + inline void XtsDecrypt(span data, size_t sector, size_t sectorSize) { XtsDecrypt(data.data(), data.data(), data.size(), sector, sectorSize); } }; diff --git a/app/src/main/cpp/skyline/gpu/gpfifo.cpp b/app/src/main/cpp/skyline/gpu/gpfifo.cpp index a8e88619..e7896467 100644 --- a/app/src/main/cpp/skyline/gpu/gpfifo.cpp +++ b/app/src/main/cpp/skyline/gpu/gpfifo.cpp @@ -89,7 +89,7 @@ namespace skyline::gpu::gpfifo { } } - void GPFIFO::Push(std::span entries) { + void GPFIFO::Push(span entries) { std::lock_guard lock(pushBufferQueueLock); bool beforeBarrier{false}; diff --git a/app/src/main/cpp/skyline/gpu/gpfifo.h b/app/src/main/cpp/skyline/gpu/gpfifo.h index 268c848c..c768612b 100644 --- a/app/src/main/cpp/skyline/gpu/gpfifo.h +++ b/app/src/main/cpp/skyline/gpu/gpfifo.h @@ -173,7 +173,7 @@ namespace skyline::gpu { /** * @brief Pushes a list of entries to the FIFO, these commands will be executed on calls to 'Step' */ - void Push(std::span entries); + void Push(span entries); }; } } diff --git a/app/src/main/cpp/skyline/gpu/memory_manager.h b/app/src/main/cpp/skyline/gpu/memory_manager.h index 459ed9e2..b1ed5a46 100644 --- a/app/src/main/cpp/skyline/gpu/memory_manager.h +++ b/app/src/main/cpp/skyline/gpu/memory_manager.h @@ -111,7 +111,7 @@ namespace skyline { * @tparam T The type of span to read into */ template - void Read(std::span destination, u64 address) const { + void Read(span destination, u64 address) const { Read(reinterpret_cast(destination.data()), address, destination.size_bytes()); } @@ -132,7 +132,7 @@ namespace skyline { * @brief Writes out a span to a region of the GPU virtual address space */ template - void Write(std::span source, u64 address) const { + void Write(span source, u64 address) const { Write(reinterpret_cast(source.data()), address, source.size_bytes()); } diff --git a/app/src/main/cpp/skyline/input/npad_device.cpp b/app/src/main/cpp/skyline/input/npad_device.cpp index 9fddf7d1..18c3e8f1 100644 --- a/app/src/main/cpp/skyline/input/npad_device.cpp +++ b/app/src/main/cpp/skyline/input/npad_device.cpp @@ -412,7 +412,7 @@ namespace skyline::input { amplitudes[i] = std::min(totalAmplitude, constant::AmplitudeMax); } - jvm->VibrateDevice(index, std::span(timings.begin(), timings.begin() + i), std::span(amplitudes.begin(), amplitudes.begin() + i)); + jvm->VibrateDevice(index, span(timings.begin(), timings.begin() + i), span(amplitudes.begin(), amplitudes.begin() + i)); } void VibrateDevice(const std::shared_ptr &jvm, i8 index, const NpadVibrationValue &value) { diff --git a/app/src/main/cpp/skyline/input/touch.cpp b/app/src/main/cpp/skyline/input/touch.cpp index 16e89424..5fb4b955 100644 --- a/app/src/main/cpp/skyline/input/touch.cpp +++ b/app/src/main/cpp/skyline/input/touch.cpp @@ -14,7 +14,7 @@ namespace skyline::input { SetState({}); } - void TouchManager::SetState(const std::span &points) { + void TouchManager::SetState(const span &points) { if (!activated) return; diff --git a/app/src/main/cpp/skyline/input/touch.h b/app/src/main/cpp/skyline/input/touch.h index b9964373..7d0005a9 100644 --- a/app/src/main/cpp/skyline/input/touch.h +++ b/app/src/main/cpp/skyline/input/touch.h @@ -37,6 +37,6 @@ namespace skyline::input { void Activate(); - void SetState(const std::span &points); + void SetState(const span &points); }; } diff --git a/app/src/main/cpp/skyline/jvm.cpp b/app/src/main/cpp/skyline/jvm.cpp index b18dd717..c462533c 100644 --- a/app/src/main/cpp/skyline/jvm.cpp +++ b/app/src/main/cpp/skyline/jvm.cpp @@ -47,7 +47,7 @@ namespace skyline { env->CallVoidMethod(instance, initializeControllersId); } - void JvmManager::VibrateDevice(jint index, const std::span &timings, const std::span &litudes) { + void JvmManager::VibrateDevice(jint index, const span &timings, const span &litudes) { auto jTimings = env->NewLongArray(timings.size()); env->SetLongArrayRegion(jTimings, 0, timings.size(), timings.data()); auto jAmplitudes = env->NewIntArray(amplitudes.size()); diff --git a/app/src/main/cpp/skyline/jvm.h b/app/src/main/cpp/skyline/jvm.h index 42e5819a..664a362f 100644 --- a/app/src/main/cpp/skyline/jvm.h +++ b/app/src/main/cpp/skyline/jvm.h @@ -97,7 +97,7 @@ namespace skyline { /** * @brief A call to EmulationActivity.vibrateDevice in Kotlin */ - void VibrateDevice(jint index, const std::span &timings, const std::span &litudes); + void VibrateDevice(jint index, const span &timings, const span &litudes); /** * @brief A call to EmulationActivity.clearVibrationDevice in Kotlin diff --git a/app/src/main/cpp/skyline/kernel/ipc.cpp b/app/src/main/cpp/skyline/kernel/ipc.cpp index e7d3a31f..9ec54ff6 100644 --- a/app/src/main/cpp/skyline/kernel/ipc.cpp +++ b/app/src/main/cpp/skyline/kernel/ipc.cpp @@ -5,16 +5,6 @@ #include "types/KProcess.h" namespace skyline::kernel::ipc { - IpcBuffer::IpcBuffer(u64 address, size_t size, IpcBufferType type) : address(address), size(size), type(type) {} - - InputBuffer::InputBuffer(kernel::ipc::BufferDescriptorX *xBuf) : IpcBuffer(xBuf->Address(), xBuf->size, IpcBufferType::X) {} - - InputBuffer::InputBuffer(kernel::ipc::BufferDescriptorABW *aBuf, IpcBufferType type) : IpcBuffer(aBuf->Address(), aBuf->Size(), type) {} - - OutputBuffer::OutputBuffer(kernel::ipc::BufferDescriptorABW *bBuf, IpcBufferType type) : IpcBuffer(bBuf->Address(), bBuf->Size(), type) {} - - OutputBuffer::OutputBuffer(kernel::ipc::BufferDescriptorC *cBuf) : IpcBuffer(cBuf->address, cBuf->size, IpcBufferType::C) {} - IpcRequest::IpcRequest(bool isDomain, const DeviceState &state) : isDomain(isDomain) { u8 *tls = state.process->GetPointer(state.thread->tls); u8 *pointer = tls; @@ -40,7 +30,7 @@ namespace skyline::kernel::ipc { for (u8 index = 0; header->xNo > index; index++) { auto bufX = reinterpret_cast(pointer); if (bufX->Address()) { - inputBuf.emplace_back(bufX); + inputBuf.emplace_back(state.process->GetPointer(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())); } pointer += sizeof(BufferDescriptorX); @@ -49,7 +39,7 @@ namespace skyline::kernel::ipc { for (u8 index = 0; header->aNo > index; index++) { auto bufA = reinterpret_cast(pointer); if (bufA->Address()) { - inputBuf.emplace_back(bufA); + inputBuf.emplace_back(state.process->GetPointer(bufA->Address()), bufA->Size()); state.logger->Debug("Buf A #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufA->Address()), u64(bufA->Size())); } pointer += sizeof(BufferDescriptorABW); @@ -58,7 +48,7 @@ namespace skyline::kernel::ipc { for (u8 index = 0; header->bNo > index; index++) { auto bufB = reinterpret_cast(pointer); if (bufB->Address()) { - outputBuf.emplace_back(bufB); + outputBuf.emplace_back(state.process->GetPointer(bufB->Address()), bufB->Size()); state.logger->Debug("Buf B #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufB->Address()), u64(bufB->Size())); } pointer += sizeof(BufferDescriptorABW); @@ -67,8 +57,8 @@ namespace skyline::kernel::ipc { for (u8 index = 0; header->wNo > index; index++) { auto bufW = reinterpret_cast(pointer); if (bufW->Address()) { - inputBuf.emplace_back(bufW, IpcBufferType::W); - outputBuf.emplace_back(bufW, IpcBufferType::W); + outputBuf.emplace_back(state.process->GetPointer(bufW->Address()), bufW->Size()); + outputBuf.emplace_back(state.process->GetPointer(bufW->Address()), bufW->Size()); state.logger->Debug("Buf W #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufW->Address()), u16(bufW->Size())); } pointer += sizeof(BufferDescriptorABW); @@ -112,14 +102,14 @@ namespace skyline::kernel::ipc { if (header->cFlag == BufferCFlag::SingleDescriptor) { auto bufC = reinterpret_cast(pointer); if (bufC->address) { - outputBuf.emplace_back(bufC); + outputBuf.emplace_back(state.process->GetPointer(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) { for (u8 index = 0; (static_cast(header->cFlag) - 2) > index; index++) { // (cFlag - 2) C descriptors are present auto bufC = reinterpret_cast(pointer); if (bufC->address) { - outputBuf.emplace_back(bufC); + outputBuf.emplace_back(state.process->GetPointer(bufC->address), u16(bufC->size)); state.logger->Debug("Buf C #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufC->address), u16(bufC->size)); } pointer += sizeof(BufferDescriptorC); diff --git a/app/src/main/cpp/skyline/kernel/ipc.h b/app/src/main/cpp/skyline/kernel/ipc.h index 9062cf9d..d0b2300a 100644 --- a/app/src/main/cpp/skyline/kernel/ipc.h +++ b/app/src/main/cpp/skyline/kernel/ipc.h @@ -196,52 +196,6 @@ namespace skyline { C //!< This is a type-C buffer }; - /** - * @brief Describes a buffer by holding the address and size - */ - struct IpcBuffer { - u64 address; //!< The address of the buffer - size_t size; //!< The size of the buffer - IpcBufferType type; //!< The type of the buffer - - /** - * @param address The address of the buffer - * @param size The size of the buffer - * @param type The type of the buffer - */ - IpcBuffer(u64 address, size_t size, IpcBufferType type); - }; - - /** - * @brief This holds an input IPC buffer - */ - struct InputBuffer : public IpcBuffer { - /** - * @param aBuf The X Buffer Descriptor that has contains the input data - */ - InputBuffer(kernel::ipc::BufferDescriptorX *xBuf); - - /** - * @param aBuf The A or W Buffer Descriptor that has contains the input data - */ - InputBuffer(kernel::ipc::BufferDescriptorABW *aBuf, IpcBufferType type = IpcBufferType::A); - }; - - /** - * @brief This holds an output IPC buffer - */ - struct OutputBuffer : public IpcBuffer { - /** - * @param bBuf The B or W Buffer Descriptor that has to be outputted to - */ - OutputBuffer(kernel::ipc::BufferDescriptorABW *bBuf, IpcBufferType type = IpcBufferType::B); - - /** - * @param cBuf The C Buffer Descriptor that has to be outputted to - */ - OutputBuffer(kernel::ipc::BufferDescriptorC *cBuf); - }; - /** * @brief This class encapsulates an IPC Request (https://switchbrew.org/wiki/IPC_Marshalling) */ @@ -260,8 +214,8 @@ namespace skyline { std::vector copyHandles; //!< A vector of handles that should be copied from the server to the client process (The difference is just to match application expectations, there is no real difference b/w copying and moving handles) std::vector moveHandles; //!< A vector of handles that should be moved from the server to the client process rather than copied std::vector domainObjects; //!< A vector of all input domain objects - std::vector inputBuf; //!< This is a vector of input buffers - std::vector outputBuf; //!< This is a vector of output buffers + std::vector> inputBuf; //!< This is a vector of input buffers + std::vector> outputBuf; //!< This is a vector of output buffers /** * @param isDomain If the following request is a domain request diff --git a/app/src/main/cpp/skyline/services/account/IAccountServiceForApplication.cpp b/app/src/main/cpp/skyline/services/account/IAccountServiceForApplication.cpp index 6f6f32b9..837788e7 100644 --- a/app/src/main/cpp/skyline/services/account/IAccountServiceForApplication.cpp +++ b/app/src/main/cpp/skyline/services/account/IAccountServiceForApplication.cpp @@ -24,7 +24,7 @@ namespace skyline::service::account { try { // We only support one active user currently so hardcode this and ListOpenUsers return WriteUserList(request.outputBuf.at(0), {constant::DefaultUserId}); - } catch (const std::out_of_range &e) { + } catch (const std::out_of_range &) { return result::InvalidInputBuffer; } } @@ -32,14 +32,13 @@ namespace skyline::service::account { Result IAccountServiceForApplication::ListOpenUsers(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { try { return WriteUserList(request.outputBuf.at(0), {constant::DefaultUserId}); - } catch (const std::out_of_range &e) { + } catch (const std::out_of_range &) { return result::InvalidInputBuffer; } } - Result IAccountServiceForApplication::WriteUserList(ipc::OutputBuffer buffer, std::vector userIds) { - std::span outputUserIds(state.process->GetPointer(buffer.address), buffer.size / sizeof(UserId)); - + Result IAccountServiceForApplication::WriteUserList(span buffer, std::vector userIds) { + span outputUserIds{buffer.cast()}; for (auto &userId : outputUserIds) { if (userIds.empty()) { userId = UserId{}; diff --git a/app/src/main/cpp/skyline/services/account/IAccountServiceForApplication.h b/app/src/main/cpp/skyline/services/account/IAccountServiceForApplication.h index 62214167..8edfeffb 100644 --- a/app/src/main/cpp/skyline/services/account/IAccountServiceForApplication.h +++ b/app/src/main/cpp/skyline/services/account/IAccountServiceForApplication.h @@ -39,7 +39,7 @@ namespace skyline { /** * @brief Writes a vector of 128-bit user IDs to an output buffer */ - Result WriteUserList(ipc::OutputBuffer buffer, std::vector userIds); + Result WriteUserList(span buffer, std::vector userIds); public: IAccountServiceForApplication(const DeviceState &state, ServiceManager &manager); diff --git a/app/src/main/cpp/skyline/services/account/IProfile.cpp b/app/src/main/cpp/skyline/services/account/IProfile.cpp index 824368b9..29d44ceb 100644 --- a/app/src/main/cpp/skyline/services/account/IProfile.cpp +++ b/app/src/main/cpp/skyline/services/account/IProfile.cpp @@ -17,8 +17,7 @@ namespace skyline::service::account { u8 _unk2_[0x60]; }; - auto userData = state.process->GetPointer(request.outputBuf.at(0).address); - userData->iconBackgroundColorID = 0x1; // Color indexing starts at 0x1 + request.outputBuf.at(0).as().iconBackgroundColorID = 0x1; // Color indexing starts at 0x1 return GetBase(session, request, response); } diff --git a/app/src/main/cpp/skyline/services/am/storage/IStorageAccessor.cpp b/app/src/main/cpp/skyline/services/am/storage/IStorageAccessor.cpp index 5bd619e9..c9a4f493 100644 --- a/app/src/main/cpp/skyline/services/am/storage/IStorageAccessor.cpp +++ b/app/src/main/cpp/skyline/services/am/storage/IStorageAccessor.cpp @@ -15,26 +15,26 @@ namespace skyline::service::am { Result IStorageAccessor::Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { auto offset = request.Pop(); - auto size = std::min(static_cast(request.inputBuf.at(0).size), static_cast(parent->content.size()) - offset); + auto size = std::min(static_cast(request.inputBuf.at(0).size()), static_cast(parent->content.size()) - offset); if (offset > parent->content.size()) return result::OutOfBounds; - if (size > 0) - state.process->ReadMemory(parent->content.data() + offset, request.inputBuf.at(0).address, size); + if (size) + request.outputBuf.at(0).copy_from(span(parent->content.data() + offset, size)); return {}; } Result IStorageAccessor::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { auto offset = request.Pop(); - auto size = std::min(static_cast(request.inputBuf.at(0).size), static_cast(parent->content.size()) - offset); + auto size = std::min(static_cast(request.inputBuf.at(0).size()), static_cast(parent->content.size()) - offset); if (offset > parent->content.size()) return result::OutOfBounds; if (size > 0) - state.process->WriteMemory(parent->content.data() + offset, request.outputBuf.at(0).address, size); + request.outputBuf.at(0).copy_from(span(parent->content.data() + offset, size)); return {}; } diff --git a/app/src/main/cpp/skyline/services/audio/IAudioDevice.cpp b/app/src/main/cpp/skyline/services/audio/IAudioDevice.cpp index ce6319ca..bb2fca10 100644 --- a/app/src/main/cpp/skyline/services/audio/IAudioDevice.cpp +++ b/app/src/main/cpp/skyline/services/audio/IAudioDevice.cpp @@ -9,13 +9,12 @@ namespace skyline::service::audio { IAudioDevice::IAudioDevice(const DeviceState &state, ServiceManager &manager) : systemEvent(std::make_shared(state)), BaseService(state, manager) {} Result IAudioDevice::ListAudioDeviceName(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - u64 offset{}; - for (std::string deviceName : {"AudioTvOutput", "AudioStereoJackOutput", "AudioBuiltInSpeakerOutput"}) { - if (offset + deviceName.size() + 1 > request.outputBuf.at(0).size) - throw exception("Too small a buffer supplied to ListAudioDeviceName"); - - state.process->WriteMemory(deviceName.c_str(), request.outputBuf.at(0).address + offset, deviceName.size() + 1); - offset += deviceName.size() + 1; + span buffer{request.outputBuf.at(0)}; + for (std::string_view deviceName : {"AudioTvOutput\0", "AudioStereoJackOutput\0", "AudioBuiltInSpeakerOutput\0"}) { + if (deviceName.size() > buffer.size()) + throw exception("The buffer supplied to ListAudioDeviceName is too small"); + buffer.copy_from(deviceName); + buffer = buffer.subspan(deviceName.size()); } return {}; } @@ -25,12 +24,10 @@ namespace skyline::service::audio { } Result IAudioDevice::GetActiveAudioDeviceName(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - std::string deviceName("AudioStereoJackOutput"); - - if (deviceName.size() > request.outputBuf.at(0).size) - throw exception("Too small a buffer supplied to GetActiveAudioDeviceName"); - - state.process->WriteMemory(deviceName.c_str(), request.outputBuf.at(0).address, deviceName.size() + 1); + std::string_view deviceName{"AudioStereoJackOutput\0"}; + if (deviceName.size() > request.outputBuf.at(0).size()) + throw exception("The buffer supplied to GetActiveAudioDeviceName is too small"); + request.outputBuf.at(0).copy_from(deviceName); return {}; } diff --git a/app/src/main/cpp/skyline/services/audio/IAudioOut.cpp b/app/src/main/cpp/skyline/services/audio/IAudioOut.cpp index 244c83e4..8ad4b134 100644 --- a/app/src/main/cpp/skyline/services/audio/IAudioOut.cpp +++ b/app/src/main/cpp/skyline/services/audio/IAudioOut.cpp @@ -37,16 +37,16 @@ namespace skyline::service::audio { u64 sampleCapacity; u64 sampleSize; u64 sampleOffset; - } &data{state.process->GetReference(request.inputBuf.at(0).address)}; + } &data{request.inputBuf.at(0).as()}; auto tag = request.Pop(); state.logger->Debug("IAudioOut: Appending buffer with address: 0x{:X}, size: 0x{:X}", data.sampleBufferPtr, data.sampleSize); if (sampleRate != constant::SampleRate) { - auto resampledBuffer = resampler.ResampleBuffer(std::span(state.process->GetPointer(data.sampleBufferPtr), data.sampleSize / sizeof(i16)), static_cast(sampleRate) / constant::SampleRate, channelCount); + auto resampledBuffer = resampler.ResampleBuffer(span(state.process->GetPointer(data.sampleBufferPtr), data.sampleSize / sizeof(i16)), static_cast(sampleRate) / constant::SampleRate, channelCount); track->AppendBuffer(tag, resampledBuffer); } else { - track->AppendBuffer(tag, std::span(state.process->GetPointer(data.sampleBufferPtr), data.sampleSize / sizeof(i16))); + track->AppendBuffer(tag, span(state.process->GetPointer(data.sampleBufferPtr), data.sampleSize / sizeof(i16))); } return {}; @@ -60,13 +60,13 @@ namespace skyline::service::audio { } Result IAudioOut::GetReleasedAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - auto maxCount{static_cast(request.outputBuf.at(0).size >> 3)}; + auto maxCount{static_cast(request.outputBuf.at(0).size() >> 3)}; std::vector releasedBuffers{track->GetReleasedBuffers(maxCount)}; auto count{static_cast(releasedBuffers.size())}; // Fill rest of output buffer with zeros releasedBuffers.resize(maxCount, 0); - state.process->WriteMemory(releasedBuffers.data(), request.outputBuf.at(0).address, request.outputBuf.at(0).size); + request.outputBuf.at(0).copy_from(releasedBuffers); response.Push(count); return {}; diff --git a/app/src/main/cpp/skyline/services/audio/IAudioOutManager.cpp b/app/src/main/cpp/skyline/services/audio/IAudioOutManager.cpp index 5eee8de3..06498d91 100644 --- a/app/src/main/cpp/skyline/services/audio/IAudioOutManager.cpp +++ b/app/src/main/cpp/skyline/services/audio/IAudioOutManager.cpp @@ -9,7 +9,7 @@ namespace skyline::service::audio { IAudioOutManager::IAudioOutManager(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {} Result IAudioOutManager::ListAudioOuts(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - state.process->WriteMemory(reinterpret_cast(const_cast(constant::DefaultAudioOutName.data())), request.outputBuf.at(0).address, constant::DefaultAudioOutName.size()); + request.outputBuf.at(0).copy_from(constant::DefaultAudioOutName); return {}; } diff --git a/app/src/main/cpp/skyline/services/audio/IAudioRenderer/IAudioRenderer.cpp b/app/src/main/cpp/skyline/services/audio/IAudioRenderer/IAudioRenderer.cpp index 4add5469..cddf12a8 100644 --- a/app/src/main/cpp/skyline/services/audio/IAudioRenderer/IAudioRenderer.cpp +++ b/app/src/main/cpp/skyline/services/audio/IAudioRenderer/IAudioRenderer.cpp @@ -45,32 +45,26 @@ namespace skyline::service::audio::IAudioRenderer { } Result IAudioRenderer::RequestUpdate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - auto inputAddress{request.inputBuf.at(0).address}; + auto input{request.inputBuf.at(0).data()}; - auto inputHeader{state.process->GetObject(inputAddress)}; + auto inputHeader{*reinterpret_cast(input)}; revisionInfo.SetUserRevision(inputHeader.revision); - inputAddress += sizeof(UpdateDataHeader); - inputAddress += inputHeader.behaviorSize; // Unused + input += sizeof(UpdateDataHeader); + input += inputHeader.behaviorSize; // Unused - auto memoryPoolCount{memoryPools.size()}; - std::vector memoryPoolsIn(memoryPoolCount); - state.process->ReadMemory(memoryPoolsIn.data(), inputAddress, memoryPoolCount * sizeof(MemoryPoolIn)); - inputAddress += inputHeader.memoryPoolSize; - - for (auto i = 0; i < memoryPoolsIn.size(); i++) + span memoryPoolsIn(reinterpret_cast(input), memoryPools.size()); + input += inputHeader.memoryPoolSize; + for (auto i = 0; i < memoryPools.size(); i++) memoryPools[i].ProcessInput(memoryPoolsIn[i]); - inputAddress += inputHeader.voiceResourceSize; - std::vector voicesIn(parameters.voiceCount); - state.process->ReadMemory(voicesIn.data(), inputAddress, parameters.voiceCount * sizeof(VoiceIn)); - inputAddress += inputHeader.voiceSize; + input += inputHeader.voiceResourceSize; + span voicesIn(reinterpret_cast(input), parameters.voiceCount); + input += inputHeader.voiceSize; for (auto i = 0; i < voicesIn.size(); i++) voices[i].ProcessInput(voicesIn[i]); - std::vector effectsIn(parameters.effectCount); - state.process->ReadMemory(effectsIn.data(), inputAddress, parameters.effectCount * sizeof(EffectIn)); - + span effectsIn(reinterpret_cast(input), parameters.effectCount); for (auto i = 0; i < effectsIn.size(); i++) effects[i].ProcessInput(effectsIn[i]); @@ -100,24 +94,24 @@ namespace skyline::service::audio::IAudioRenderer { outputHeader.performanceManagerSize + outputHeader.elapsedFrameCountInfoSize; - u64 outputAddress = request.outputBuf.at(0).address; + auto output{request.outputBuf.at(0).data()}; - state.process->WriteMemory(outputHeader, outputAddress); - outputAddress += sizeof(UpdateDataHeader); + *reinterpret_cast(output) = outputHeader; + output += sizeof(UpdateDataHeader); for (const auto &memoryPool : memoryPools) { - state.process->WriteMemory(memoryPool.output, outputAddress); - outputAddress += sizeof(MemoryPoolOut); + *reinterpret_cast(output) = memoryPool.output; + output += sizeof(MemoryPoolOut); } for (const auto &voice : voices) { - state.process->WriteMemory(voice.output, outputAddress); - outputAddress += sizeof(VoiceOut); + *reinterpret_cast(output) = voice.output; + output += sizeof(VoiceOut); } for (const auto &effect : effects) { - state.process->WriteMemory(effect.output, outputAddress); - outputAddress += sizeof(EffectOut); + *reinterpret_cast(output) = effect.output; + output += sizeof(EffectOut); } return {}; diff --git a/app/src/main/cpp/skyline/services/audio/IAudioRenderer/voice.cpp b/app/src/main/cpp/skyline/services/audio/IAudioRenderer/voice.cpp index f858d4cb..cd49f27c 100644 --- a/app/src/main/cpp/skyline/services/audio/IAudioRenderer/voice.cpp +++ b/app/src/main/cpp/skyline/services/audio/IAudioRenderer/voice.cpp @@ -68,7 +68,7 @@ namespace skyline::service::audio::IAudioRenderer { state.process->ReadMemory(samples.data(), currentBuffer.address, currentBuffer.size); break; case skyline::audio::AudioFormat::ADPCM: { - samples = adpcmDecoder->Decode(std::span(state.process->GetPointer(currentBuffer.address), currentBuffer.size)); + samples = adpcmDecoder->Decode(span(state.process->GetPointer(currentBuffer.address), currentBuffer.size)); break; } default: diff --git a/app/src/main/cpp/skyline/services/common/parcel.cpp b/app/src/main/cpp/skyline/services/common/parcel.cpp index 29d0c497..652f4d53 100644 --- a/app/src/main/cpp/skyline/services/common/parcel.cpp +++ b/app/src/main/cpp/skyline/services/common/parcel.cpp @@ -6,30 +6,24 @@ #include "parcel.h" namespace skyline::service { - Parcel::Parcel(kernel::ipc::InputBuffer &buffer, const DeviceState &state, bool hasToken) : Parcel(buffer.address, buffer.size, state, hasToken) {} + Parcel::Parcel(span buffer, const DeviceState &state, bool hasToken) : state(state) { + header = buffer.as(); - Parcel::Parcel(u64 address, u64 size, const DeviceState &state, bool hasToken) : state(state) { - state.process->ReadMemory(&header, address, sizeof(ParcelHeader)); - - if (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"); constexpr auto tokenLength = 0x50; // The length of the token on BufferQueue parcels data.resize(header.dataSize - (hasToken ? tokenLength : 0)); - state.process->ReadMemory(data.data(), address + 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)); objects.resize(header.objectsSize); - state.process->ReadMemory(objects.data(), address + header.objectsOffset, header.objectsSize); + memcpy(objects.data(), buffer.data() + header.objectsOffset, header.objectsSize); } Parcel::Parcel(const DeviceState &state) : state(state) {} - u64 Parcel::WriteParcel(kernel::ipc::OutputBuffer &buffer) { - return WriteParcel(buffer.address, buffer.size); - } - - u64 Parcel::WriteParcel(u64 address, u64 maxSize) { + u64 Parcel::WriteParcel(span buffer) { header.dataSize = static_cast(data.size()); header.dataOffset = sizeof(ParcelHeader); @@ -38,12 +32,12 @@ namespace skyline::service { auto totalSize = sizeof(ParcelHeader) + header.dataSize + header.objectsSize; - if (maxSize < totalSize) + if (buffer.size() < totalSize) throw exception("The size of the parcel exceeds maxSize"); - state.process->WriteMemory(header, address); - state.process->WriteMemory(data.data(), address + header.dataOffset, data.size()); - state.process->WriteMemory(objects.data(), address + header.objectsOffset, objects.size()); + buffer.as() = header; + memcpy(buffer.data() + header.dataOffset, data.data(), data.size()); + memcpy(buffer.data() + header.objectsOffset, objects.data(), objects.size()); return totalSize; } diff --git a/app/src/main/cpp/skyline/services/common/parcel.h b/app/src/main/cpp/skyline/services/common/parcel.h index a9709b98..69b8b110 100644 --- a/app/src/main/cpp/skyline/services/common/parcel.h +++ b/app/src/main/cpp/skyline/services/common/parcel.h @@ -36,16 +36,7 @@ namespace skyline::service { * @param state The state of the device * @param hasToken If the parcel starts with a token, it is skipped if this flag is true */ - Parcel(kernel::ipc::InputBuffer &buffer, const DeviceState &state, bool hasToken = false); - - /** - * @brief This constructor fills in the Parcel object with data from a Parcel on a remote process - * @param address The remote address of the parcel - * @param size The size of the parcel - * @param state The state of the device - * @param hasToken If the parcel starts with a token, it is skipped if this flag is true - */ - Parcel(u64 address, u64 size, const DeviceState &state, bool hasToken = false); + Parcel(span buffer, const DeviceState &state, bool hasToken = false); /** * @brief This constructor is used to create an empty parcel then write to a process @@ -94,18 +85,10 @@ namespace skyline::service { } /** - * @brief Writes the Parcel object into a particular output buffer on a process - * @param buffer The buffer to write into + * @brief Writes the Parcel object out + * @param buffer The buffer to write the Parcel object to * @return The total size of the message */ - u64 WriteParcel(kernel::ipc::OutputBuffer &buffer); - - /** - * @brief Writes the Parcel object into the process's memory - * @param address The address to write the Parcel object to - * @param maxSize The maximum size of the Parcel - * @return The total size of the message - */ - u64 WriteParcel(u64 address, u64 maxSize); + u64 WriteParcel(span buffer); }; } diff --git a/app/src/main/cpp/skyline/services/fssrv/IFile.cpp b/app/src/main/cpp/skyline/services/fssrv/IFile.cpp index 3ac5140f..d5df1cb8 100644 --- a/app/src/main/cpp/skyline/services/fssrv/IFile.cpp +++ b/app/src/main/cpp/skyline/services/fssrv/IFile.cpp @@ -24,7 +24,7 @@ namespace skyline::service::fssrv { return result::InvalidSize; } - response.Push(static_cast(backing->Read(state.process->GetPointer(request.outputBuf.at(0).address), offset, size))); + response.Push(static_cast(backing->Read(request.outputBuf.at(0).data(), offset, size))); return {}; } @@ -44,12 +44,12 @@ namespace skyline::service::fssrv { return result::InvalidSize; } - if (request.inputBuf.at(0).size < size) { + if (request.inputBuf.at(0).size() < size) { state.logger->Warn("The input buffer is not large enough to fit the requested size"); return result::InvalidSize; } - if (backing->Write(state.process->GetPointer(request.inputBuf.at(0).address), offset, request.inputBuf.at(0).size) != size) { + if (backing->Write(request.inputBuf.at(0).data(), offset, request.inputBuf.at(0).size()) != size) { state.logger->Warn("Failed to write all data to the backing"); return result::UnexpectedFailure; } diff --git a/app/src/main/cpp/skyline/services/fssrv/IFileSystem.cpp b/app/src/main/cpp/skyline/services/fssrv/IFileSystem.cpp index 73656ef6..e1c3c657 100644 --- a/app/src/main/cpp/skyline/services/fssrv/IFileSystem.cpp +++ b/app/src/main/cpp/skyline/services/fssrv/IFileSystem.cpp @@ -11,7 +11,7 @@ namespace skyline::service::fssrv { IFileSystem::IFileSystem(std::shared_ptr backing, const DeviceState &state, ServiceManager &manager) : backing(backing), BaseService(state, manager) {} Result IFileSystem::CreateFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - std::string path = std::string(state.process->GetPointer(request.inputBuf.at(0).address)); + std::string path{request.inputBuf.at(0).as()}; auto mode = request.Pop(); auto size = request.Pop(); @@ -19,7 +19,7 @@ namespace skyline::service::fssrv { } Result IFileSystem::GetEntryType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - std::string path = std::string(state.process->GetPointer(request.inputBuf.at(0).address)); + std::string path{request.inputBuf.at(0).as()}; auto type = backing->GetEntryType(path); @@ -33,7 +33,7 @@ namespace skyline::service::fssrv { } Result IFileSystem::OpenFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - std::string path(state.process->GetPointer(request.inputBuf.at(0).address)); + std::string path{request.inputBuf.at(0).as()}; auto mode = request.Pop(); if (!backing->FileExists(path)) diff --git a/app/src/main/cpp/skyline/services/fssrv/IStorage.cpp b/app/src/main/cpp/skyline/services/fssrv/IStorage.cpp index 72b09f4f..7799a6ad 100644 --- a/app/src/main/cpp/skyline/services/fssrv/IStorage.cpp +++ b/app/src/main/cpp/skyline/services/fssrv/IStorage.cpp @@ -22,7 +22,7 @@ namespace skyline::service::fssrv { return result::InvalidSize; } - backing->Read(state.process->GetPointer(request.outputBuf.at(0).address), offset, size); + backing->Read(request.outputBuf.at(0).data(), offset, size); return {}; } diff --git a/app/src/main/cpp/skyline/services/hid/IHidServer.cpp b/app/src/main/cpp/skyline/services/hid/IHidServer.cpp index 7f291be8..103ed3e1 100644 --- a/app/src/main/cpp/skyline/services/hid/IHidServer.cpp +++ b/app/src/main/cpp/skyline/services/hid/IHidServer.cpp @@ -41,18 +41,9 @@ namespace skyline::service::hid { } Result IHidServer::SetSupportedNpadIdType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - const auto &buffer = request.inputBuf.at(0); - u64 address = buffer.address; - size_t size = buffer.size / sizeof(NpadId); - - std::vector supportedIds(size); - for (size_t i = 0; i < size; i++) { - supportedIds[i] = state.process->GetObject(address); - address += sizeof(NpadId); - } - + auto supportedIds{request.inputBuf.at(0).cast()}; std::lock_guard lock(state.input->npad.mutex); - state.input->npad.supportedIds = supportedIds; + state.input->npad.supportedIds.assign(supportedIds.begin(), supportedIds.end()); state.input->npad.Update(); return {}; } @@ -150,10 +141,8 @@ namespace skyline::service::hid { Result IHidServer::SendVibrationValues(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { request.Skip(); // appletResourceUserId - auto &handleBuf = request.inputBuf.at(0); - std::span handles(reinterpret_cast(handleBuf.address), handleBuf.size / sizeof(NpadDeviceHandle)); - auto &valueBuf = request.inputBuf.at(1); - std::span values(reinterpret_cast(valueBuf.address), valueBuf.size / sizeof(NpadVibrationValue)); + auto handles{request.inputBuf.at(0).cast()}; + auto values{request.inputBuf.at(1).cast()}; for (size_t i{}; i < handles.size(); ++i) { const auto &handle = handles[i]; diff --git a/app/src/main/cpp/skyline/services/lm/ILogger.cpp b/app/src/main/cpp/skyline/services/lm/ILogger.cpp index 065f9e1d..0838a321 100644 --- a/app/src/main/cpp/skyline/services/lm/ILogger.cpp +++ b/app/src/main/cpp/skyline/services/lm/ILogger.cpp @@ -40,16 +40,16 @@ namespace skyline::service::lm { LogLevel level; u8 verbosity; u32 payloadLength; - } &data = state.process->GetReference(request.inputBuf.at(0).address); + } &data = request.inputBuf.at(0).as(); std::ostringstream logMessage; logMessage << "Guest log:"; u64 offset = sizeof(Data); - while (offset < request.inputBuf.at(0).size) { - auto fieldType = state.process->GetObject(request.inputBuf.at(0).address + offset++); - auto length = state.process->GetObject(request.inputBuf.at(0).address + offset++); - auto address = request.inputBuf.at(0).address + offset; + while (offset < request.inputBuf[0].size()) { + auto fieldType = request.inputBuf[0].subspan(offset++).as(); + auto length = request.inputBuf[0].subspan(offset++).as(); + auto object = request.inputBuf[0].subspan(offset, length); logMessage << " "; @@ -58,24 +58,25 @@ namespace skyline::service::lm { offset += length; continue; case LogFieldType::Line: - logMessage << GetFieldName(fieldType) << ": " << state.process->GetObject(address); + logMessage << GetFieldName(fieldType) << ": " << object.as(); offset += sizeof(u32); continue; case LogFieldType::DropCount: - logMessage << GetFieldName(fieldType) << ": " << state.process->GetObject(address); + logMessage << GetFieldName(fieldType) << ": " << object.as(); offset += sizeof(u64); continue; case LogFieldType::Time: - logMessage << GetFieldName(fieldType) << ": " << state.process->GetObject(address) << "s"; + logMessage << GetFieldName(fieldType) << ": " << object.as() << "s"; offset += sizeof(u64); continue; case LogFieldType::Stop: break; default: - logMessage << GetFieldName(fieldType) << ": " << state.process->GetString(address, length); + logMessage << GetFieldName(fieldType) << ": " << object.as_string(); offset += length; continue; } + break; } diff --git a/app/src/main/cpp/skyline/services/nvdrv/INvDrvServices.cpp b/app/src/main/cpp/skyline/services/nvdrv/INvDrvServices.cpp index c1897a5d..750d25fe 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/INvDrvServices.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/INvDrvServices.cpp @@ -13,8 +13,7 @@ namespace skyline::service::nvdrv { } Result INvDrvServices::Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - auto buffer = request.inputBuf.at(0); - auto path = state.process->GetString(buffer.address, buffer.size); + auto path{request.inputBuf.at(0).as_string()}; response.Push(driver->OpenDevice(path)); response.Push(device::NvStatus::Success); @@ -31,7 +30,7 @@ namespace skyline::service::nvdrv { // Strip the permissions from the command leaving only the ID cmd &= 0xFFFF; - std::optional buffer{std::nullopt}; + span buffer{}; if (request.inputBuf.empty() || request.outputBuf.empty()) { if (!request.inputBuf.empty()) buffer = request.inputBuf.at(0); @@ -39,13 +38,16 @@ namespace skyline::service::nvdrv { buffer = request.outputBuf.at(0); else throw exception("No IOCTL Buffers"); - } else if (request.inputBuf.at(0).address == request.outputBuf.at(0).address) { - buffer = request.inputBuf.at(0); + } else if (request.inputBuf[0].data() == request.outputBuf[0].data()) { + if (request.inputBuf[0].size() >= request.outputBuf[0].size()) + buffer = request.inputBuf[0]; + else + buffer = request.outputBuf[0]; } else { - throw exception("IOCTL Input Buffer (0x{:X}) != Output Buffer (0x{:X})", request.inputBuf[0].address, request.outputBuf[0].address); + throw exception("IOCTL Input Buffer (0x{:X}) != Output Buffer (0x{:X})", fmt::ptr(request.inputBuf[0].data()), fmt::ptr(request.outputBuf[0].data())); } - response.Push(device->HandleIoctl(cmd, device::IoctlType::Ioctl, std::span(reinterpret_cast(buffer->address), buffer->size), {})); + response.Push(device->HandleIoctl(cmd, device::IoctlType::Ioctl, buffer, {})); return {}; } @@ -101,10 +103,16 @@ namespace skyline::service::nvdrv { if (request.inputBuf.size() < 2 || request.outputBuf.empty()) throw exception("Inadequate amount of buffers for IOCTL2: I - {}, O - {}", request.inputBuf.size(), request.outputBuf.size()); - else if (request.inputBuf[0].address != request.outputBuf[0].address) - throw exception("IOCTL2 Input Buffer (0x{:X}) != Output Buffer (0x{:X}) [Input Buffer #2: 0x{:X}]", request.inputBuf[0].address, request.outputBuf[0].address, request.inputBuf[1].address); + else if (request.inputBuf[0].data() != request.outputBuf[0].data()) + throw exception("IOCTL2 Input Buffer (0x{:X}) != Output Buffer (0x{:X}) [Input Buffer #2: 0x{:X}]", fmt::ptr(request.inputBuf[0].data()), fmt::ptr(request.outputBuf[0].data()), fmt::ptr(request.inputBuf[1].data())); - response.Push(device->HandleIoctl(cmd, device::IoctlType::Ioctl2, std::span(reinterpret_cast(request.inputBuf[0].address), request.inputBuf[0].size), std::span(reinterpret_cast(request.inputBuf[1].address), request.inputBuf[1].size))); + span buffer{}; + if (request.inputBuf[0].size() >= request.outputBuf[0].size()) + buffer = request.inputBuf[0]; + else + buffer = request.outputBuf[0]; + + response.Push(device->HandleIoctl(cmd, device::IoctlType::Ioctl2, buffer, request.inputBuf[1])); return {}; } @@ -119,10 +127,16 @@ namespace skyline::service::nvdrv { if (request.inputBuf.empty() || request.outputBuf.size() < 2) throw exception("Inadequate amount of buffers for IOCTL3: I - {}, O - {}", request.inputBuf.size(), request.outputBuf.size()); - else if (request.inputBuf[0].address != request.outputBuf[0].address) - throw exception("IOCTL3 Input Buffer (0x{:X}) != Output Buffer (0x{:X}) [Output Buffer #2: 0x{:X}]", request.inputBuf[0].address, request.outputBuf[0].address, request.outputBuf[1].address); + else if (request.inputBuf[0].data() != request.outputBuf[0].data()) + throw exception("IOCTL3 Input Buffer (0x{:X}) != Output Buffer (0x{:X}) [Output Buffer #2: 0x{:X}]", fmt::ptr(request.inputBuf[0].data()), fmt::ptr(request.outputBuf[0].data()), fmt::ptr(request.outputBuf[1].data())); - response.Push(device->HandleIoctl(cmd, device::IoctlType::Ioctl3, std::span(reinterpret_cast(request.inputBuf[0].address), request.inputBuf[0].size), std::span(reinterpret_cast(request.outputBuf[1].address), request.outputBuf[1].size))); + span buffer{}; + if (request.inputBuf[0].size() >= request.outputBuf[0].size()) + buffer = request.inputBuf[0]; + else + buffer = request.outputBuf[0]; + + response.Push(device->HandleIoctl(cmd, device::IoctlType::Ioctl3, buffer, request.outputBuf[1])); return {}; } diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.cpp index 1450c315..ddd49aa8 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.cpp @@ -17,7 +17,7 @@ namespace skyline::service::nvdrv::device { return name; } - NvStatus NvDevice::HandleIoctl(u32 cmd, IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvDevice::HandleIoctl(u32 cmd, IoctlType type, span buffer, span inlineBuffer) { std::string_view typeString{[type] { switch (type) { case IoctlType::Ioctl: @@ -29,7 +29,7 @@ namespace skyline::service::nvdrv::device { } }()}; - std::pair, std::span)>, std::string_view> function; + std::pair, span)>, std::string_view> function; try { function = GetIoctlFunction(cmd); state.logger->Debug("{} @ {}: {}", typeString, GetName(), function.second); diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.h index 82ad4690..ed5f57c7 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.h @@ -8,11 +8,11 @@ #include #include -#define NVFUNC(id, Class, Function) std::pair, std::span)>, std::string_view>>{id, {&Class::Function, #Function}} +#define NVFUNC(id, Class, Function) std::pair, span)>, std::string_view>>{id, {&Class::Function, #Function}} #define NVDEVICE_DECL_AUTO(name, value) decltype(value) name = value #define NVDEVICE_DECL(...) \ NVDEVICE_DECL_AUTO(functions, frz::make_unordered_map({__VA_ARGS__})); \ -std::pair, std::span)>, std::string_view> GetIoctlFunction(u32 id) { \ +std::pair, span)>, std::string_view> GetIoctlFunction(u32 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); \ } @@ -73,7 +73,7 @@ namespace skyline::service::nvdrv::device { virtual ~NvDevice() = default; - virtual std::pair, std::span)>, std::string_view> GetIoctlFunction(u32 id) = 0; + virtual std::pair, span)>, std::string_view> GetIoctlFunction(u32 id) = 0; /** * @return The name of the class @@ -85,7 +85,7 @@ namespace skyline::service::nvdrv::device { * @brief This handles IOCTL calls for devices * @param cmd The IOCTL command that was called */ - NvStatus HandleIoctl(u32 cmd, IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus HandleIoctl(u32 cmd, IoctlType type, span buffer, span inlineBuffer); inline virtual std::shared_ptr QueryEvent(u32 eventId) { return nullptr; diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.cpp index c0aae8c3..c0c3420e 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.cpp @@ -11,11 +11,11 @@ namespace skyline::service::nvdrv::device { NvHostAsGpu::NvHostAsGpu(const DeviceState &state) : NvDevice(state) {} - NvStatus NvHostAsGpu::BindChannel(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostAsGpu::BindChannel(IoctlType type, span buffer, span inlineBuffer) { return NvStatus::Success; } - NvStatus NvHostAsGpu::AllocSpace(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostAsGpu::AllocSpace(IoctlType type, span buffer, span inlineBuffer) { struct Data { u32 pages; // In u32 pageSize; // In @@ -25,7 +25,7 @@ namespace skyline::service::nvdrv::device { u64 offset; // InOut u64 align; // In }; - } region = util::As(buffer); + } region = buffer.as(); u64 size = static_cast(region.pages) * static_cast(region.pageSize); @@ -42,8 +42,8 @@ namespace skyline::service::nvdrv::device { return NvStatus::Success; } - NvStatus NvHostAsGpu::UnmapBuffer(IoctlType type, std::span buffer, std::span inlineBuffer) { - u64 offset{util::As(buffer)}; + NvStatus NvHostAsGpu::UnmapBuffer(IoctlType type, span buffer, span inlineBuffer) { + u64 offset{buffer.as()}; if (!state.gpu->memoryManager.Unmap(offset)) state.logger->Warn("Failed to unmap chunk at 0x{:X}", offset); @@ -51,7 +51,7 @@ namespace skyline::service::nvdrv::device { return NvStatus::Success; } - NvStatus NvHostAsGpu::Modify(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostAsGpu::Modify(IoctlType type, span buffer, span inlineBuffer) { struct Data { u32 flags; // In u32 kind; // In @@ -60,7 +60,7 @@ namespace skyline::service::nvdrv::device { u64 bufferOffset; // In u64 mappingSize; // In u64 offset; // InOut - } &data = util::As(buffer); + } &data = buffer.as(); try { auto driver = nvdrv::driver.lock(); @@ -87,7 +87,7 @@ namespace skyline::service::nvdrv::device { } } - NvStatus NvHostAsGpu::GetVaRegions(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostAsGpu::GetVaRegions(IoctlType type, span buffer, span inlineBuffer) { /* struct Data { u64 _pad0_; @@ -100,12 +100,12 @@ namespace skyline::service::nvdrv::device { u32 pad; u64 pages; } regions[2]; // Out - } ®ionInfo = util::As(buffer); + } ®ionInfo = buffer.as(); */ return NvStatus::Success; } - NvStatus NvHostAsGpu::AllocAsEx(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostAsGpu::AllocAsEx(IoctlType type, span buffer, span inlineBuffer) { /* struct Data { u32 bigPageSize; // In @@ -115,12 +115,12 @@ namespace skyline::service::nvdrv::device { u64 vaRangeStart; // In u64 vaRangeEnd; // In u64 vaRangeSplit; // In - } addressSpace = util::As(buffer); + } addressSpace = buffer.as(); */ return NvStatus::Success; } - NvStatus NvHostAsGpu::Remap(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostAsGpu::Remap(IoctlType type, span buffer, span inlineBuffer) { struct Entry { u16 flags; // In u16 kind; // In @@ -132,7 +132,7 @@ namespace skyline::service::nvdrv::device { constexpr u32 MinAlignmentShift{0x10}; // This shift is applied to all addresses passed to Remap - auto entries{util::AsSpan(buffer)}; + auto entries{buffer.cast()}; for (auto entry : entries) { try { auto driver = nvdrv::driver.lock(); diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.h index 7b4eabfa..38c3ffa3 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.h @@ -16,37 +16,37 @@ namespace skyline::service::nvdrv::device { /** * @brief This binds a channel to the address space (https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_BIND_CHANNEL) */ - NvStatus BindChannel(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus BindChannel(IoctlType type, span buffer, span inlineBuffer); /** * @brief This reserves a region in the GPU address space (https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_ALLOC_SPACE) */ - NvStatus AllocSpace(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus AllocSpace(IoctlType type, span buffer, span inlineBuffer); /** * @brief This unmaps a region in the GPU address space (https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_UNMAP_BUFFER) */ - NvStatus UnmapBuffer(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus UnmapBuffer(IoctlType type, span buffer, span inlineBuffer); /** * @brief This maps a region in the GPU address space (https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_MODIFY) */ - NvStatus Modify(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus Modify(IoctlType type, span buffer, span inlineBuffer); /** * @brief This returns the application's GPU address space (https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_GET_VA_REGIONS) */ - NvStatus GetVaRegions(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus GetVaRegions(IoctlType type, span buffer, span inlineBuffer); /** * @brief This initializes the application's GPU address space (https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_ALLOC_AS_EX) */ - NvStatus AllocAsEx(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus AllocAsEx(IoctlType type, span buffer, span inlineBuffer); /** * @brief Remaps a region of the GPU address space (https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_REMAP) */ - NvStatus Remap(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus Remap(IoctlType type, span buffer, span inlineBuffer); NVDEVICE_DECL( NVFUNC(0x4101, NvHostAsGpu, BindChannel), diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp index e2715755..757fef02 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp @@ -16,15 +16,15 @@ namespace skyline::service::nvdrv::device { channelFence.UpdateValue(hostSyncpoint); } - NvStatus NvHostChannel::SetNvmapFd(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostChannel::SetNvmapFd(IoctlType type, span buffer, span inlineBuffer) { return NvStatus::Success; } - NvStatus NvHostChannel::SetSubmitTimeout(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostChannel::SetSubmitTimeout(IoctlType type, span buffer, span inlineBuffer) { return NvStatus::Success; } - NvStatus NvHostChannel::SubmitGpfifo(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostChannel::SubmitGpfifo(IoctlType type, span buffer, span inlineBuffer) { struct Data { u64 address; // In u32 numEntries; // In @@ -41,7 +41,7 @@ namespace skyline::service::nvdrv::device { u32 raw; } flags; // In Fence fence; // InOut - } &data = util::As(buffer); + } &data = buffer.as(); auto driver = nvdrv::driver.lock(); auto &hostSyncpoint = driver->hostSyncpoint; @@ -54,7 +54,7 @@ namespace skyline::service::nvdrv::device { throw exception("Waiting on a fence through SubmitGpfifo is unimplemented"); } - state.gpu->gpfifo.Push(std::span(state.process->GetPointer(data.address), data.numEntries)); + state.gpu->gpfifo.Push(span(state.process->GetPointer(data.address), data.numEntries)); data.fence.id = channelFence.id; @@ -69,20 +69,20 @@ namespace skyline::service::nvdrv::device { return NvStatus::Success; } - NvStatus NvHostChannel::AllocObjCtx(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostChannel::AllocObjCtx(IoctlType type, span buffer, span inlineBuffer) { return NvStatus::Success; } - NvStatus NvHostChannel::ZcullBind(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostChannel::ZcullBind(IoctlType type, span buffer, span inlineBuffer) { return NvStatus::Success; } - NvStatus NvHostChannel::SetErrorNotifier(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostChannel::SetErrorNotifier(IoctlType type, span buffer, span inlineBuffer) { return NvStatus::Success; } - NvStatus NvHostChannel::SetPriority(IoctlType type, std::span buffer, std::span inlineBuffer) { - switch (util::As(buffer)) { + NvStatus NvHostChannel::SetPriority(IoctlType type, span buffer, span inlineBuffer) { + switch (buffer.as()) { case NvChannelPriority::Low: timeslice = 1300; break; @@ -97,14 +97,14 @@ namespace skyline::service::nvdrv::device { return NvStatus::Success; } - NvStatus NvHostChannel::AllocGpfifoEx2(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostChannel::AllocGpfifoEx2(IoctlType type, span buffer, span inlineBuffer) { struct Data { u32 numEntries; // In u32 numJobs; // In u32 flags; // In Fence fence; // Out u32 reserved[3]; // In - } &data = util::As(buffer); + } &data = buffer.as(); auto driver = nvdrv::driver.lock(); channelFence.UpdateValue(driver->hostSyncpoint); @@ -113,7 +113,7 @@ namespace skyline::service::nvdrv::device { return NvStatus::Success; } - NvStatus NvHostChannel::SetUserData(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostChannel::SetUserData(IoctlType type, span buffer, span inlineBuffer) { return NvStatus::Success; } diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.h index 236ebd85..1b4acf45 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.h @@ -30,47 +30,47 @@ namespace skyline::service::nvdrv::device { /** * @brief This sets the nvmap file descriptor (https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_SET_NVMAP_FD) */ - NvStatus SetNvmapFd(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus SetNvmapFd(IoctlType type, span buffer, span inlineBuffer); /** * @brief This sets the timeout for the channel (https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CHANNEL_SET_SUBMIT_TIMEOUT) */ - NvStatus SetSubmitTimeout(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus SetSubmitTimeout(IoctlType type, span buffer, span inlineBuffer); /** * @brief This submits a command to the GPFIFO (https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_SUBMIT_GPFIFO) */ - NvStatus SubmitGpfifo(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus SubmitGpfifo(IoctlType type, span buffer, span inlineBuffer); /** * @brief This allocates a graphic context object (https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_ALLOC_OBJ_CTX) */ - NvStatus AllocObjCtx(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus AllocObjCtx(IoctlType type, span buffer, span inlineBuffer); /** * @brief This initializes the error notifier for this channel (https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_ZCULL_BIND) */ - NvStatus ZcullBind(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus ZcullBind(IoctlType type, span buffer, span inlineBuffer); /** * @brief This initializes the error notifier for this channel (https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_SET_ERROR_NOTIFIER) */ - NvStatus SetErrorNotifier(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus SetErrorNotifier(IoctlType type, span buffer, span inlineBuffer); /** * @brief This sets the priority of the channel (https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_SET_PRIORITY) */ - NvStatus SetPriority(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus SetPriority(IoctlType type, span buffer, span inlineBuffer); /** * @brief This allocates a GPFIFO entry (https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_ALLOC_GPFIFO_EX2) */ - NvStatus AllocGpfifoEx2(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus AllocGpfifoEx2(IoctlType type, span buffer, span inlineBuffer); /** * @brief This sets the user specific data (https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_SET_USER_DATA) */ - NvStatus SetUserData(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus SetUserData(IoctlType type, span buffer, span inlineBuffer); std::shared_ptr QueryEvent(u32 eventId); diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp index 46bb21ef..33ff87a2 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp @@ -72,12 +72,12 @@ namespace skyline::service::nvdrv::device { throw exception("Failed to find a free nvhost event!"); } - NvStatus NvHostCtrl::EventWaitImpl(std::span buffer, bool async) { + NvStatus NvHostCtrl::EventWaitImpl(span buffer, bool async) { struct Data { Fence fence; // In u32 timeout; // In EventValue value; // InOut - } &data = util::As(buffer); + } &data = buffer.as(); if (data.fence.id >= constant::MaxHwSyncpointCount) return NvStatus::BadValue; @@ -135,12 +135,12 @@ namespace skyline::service::nvdrv::device { } } - NvStatus NvHostCtrl::GetConfig(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostCtrl::GetConfig(IoctlType type, span buffer, span inlineBuffer) { return NvStatus::BadValue; } - NvStatus NvHostCtrl::EventSignal(IoctlType type, std::span buffer, std::span inlineBuffer) { - auto userEventId{util::As(buffer)}; + NvStatus NvHostCtrl::EventSignal(IoctlType type, span buffer, span inlineBuffer) { + auto userEventId{buffer.as()}; state.logger->Debug("Signalling nvhost event: {}", userEventId); if (userEventId >= constant::NvHostEventCount || !events.at(userEventId)) @@ -163,16 +163,16 @@ namespace skyline::service::nvdrv::device { return NvStatus::Success; } - NvStatus NvHostCtrl::EventWait(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostCtrl::EventWait(IoctlType type, span buffer, span inlineBuffer) { return EventWaitImpl(buffer, false); } - NvStatus NvHostCtrl::EventWaitAsync(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostCtrl::EventWaitAsync(IoctlType type, span buffer, span inlineBuffer) { return EventWaitImpl(buffer, true); } - NvStatus NvHostCtrl::EventRegister(IoctlType type, std::span buffer, std::span inlineBuffer) { - auto userEventId{util::As(buffer)}; + NvStatus NvHostCtrl::EventRegister(IoctlType type, span buffer, span inlineBuffer) { + auto userEventId{buffer.as()}; state.logger->Debug("Registering nvhost event: {}", userEventId); auto &event = events.at(userEventId); diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h index 7fa2653c..e96956b7 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h @@ -87,7 +87,7 @@ namespace skyline { */ u32 FindFreeEvent(u32 syncpointId); - NvStatus EventWaitImpl(std::span buffer, bool async); + NvStatus EventWaitImpl(span buffer, bool async); public: NvHostCtrl(const DeviceState &state); @@ -95,27 +95,27 @@ namespace skyline { /** * @brief This gets the value of an nvdrv setting, it returns an error code on production switches (https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CTRL_GET_CONFIG) */ - NvStatus GetConfig(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus GetConfig(IoctlType type, span buffer, span inlineBuffer); /** * @brief This signals an NvHost event (https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CTRL_EVENT_SIGNAL) */ - NvStatus EventSignal(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus EventSignal(IoctlType type, span buffer, span inlineBuffer); /** * @brief This synchronously waits on an NvHost event (https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CTRL_EVENT_WAIT) */ - NvStatus EventWait(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus EventWait(IoctlType type, span buffer, span inlineBuffer); /** * @brief This asynchronously waits on an NvHost event (https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CTRL_EVENT_WAIT_ASYNC) */ - NvStatus EventWaitAsync(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus EventWaitAsync(IoctlType type, span buffer, span inlineBuffer); /** * @brief This registers an NvHost event (https://switchbrew.org/wiki/NV_services#NVHOST_IOCTL_CTRL_EVENT_REGISTER) */ - NvStatus EventRegister(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus EventRegister(IoctlType type, span buffer, span inlineBuffer); std::shared_ptr QueryEvent(u32 eventId); diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp index fc35007b..524d1994 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -7,12 +7,12 @@ namespace skyline::service::nvdrv::device { NvHostCtrlGpu::NvHostCtrlGpu(const DeviceState &state) : errorNotifierEvent(std::make_shared(state)), unknownEvent(std::make_shared(state)), NvDevice(state) {} - NvStatus NvHostCtrlGpu::ZCullGetCtxSize(IoctlType type, std::span buffer, std::span inlineBuffer) { - util::As(buffer) = 0x1; + NvStatus NvHostCtrlGpu::ZCullGetCtxSize(IoctlType type, span buffer, span inlineBuffer) { + buffer.as() = 0x1; return NvStatus::Success; } - NvStatus NvHostCtrlGpu::ZCullGetInfo(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostCtrlGpu::ZCullGetInfo(IoctlType type, span buffer, span inlineBuffer) { struct ZCullInfo { u32 widthAlignPixels{0x20}; u32 heightAlignPixels{0x20}; @@ -26,11 +26,11 @@ namespace skyline::service::nvdrv::device { u32 subregionCount{0x10}; } zCullInfo; - util::As(buffer) = zCullInfo; + buffer.as() = zCullInfo; return NvStatus::Success; } - NvStatus NvHostCtrlGpu::GetCharacteristics(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostCtrlGpu::GetCharacteristics(IoctlType type, span buffer, span inlineBuffer) { struct GpuCharacteristics { u32 arch{0x120}; // NVGPU_GPU_ARCH_GM200 u32 impl{0xB}; // 0xB (NVGPU_GPU_IMPL_GM20B) or 0xE (NVGPU_GPU_IMPL_GM20B_B) @@ -73,7 +73,7 @@ namespace skyline::service::nvdrv::device { u64 gpuCharacteristicsBufSize; // InOut u64 gpuCharacteristicsBufAddr; // In GpuCharacteristics gpuCharacteristics; // Out - } &data = util::As(buffer); + } &data = buffer.as(); if (data.gpuCharacteristicsBufSize < sizeof(GpuCharacteristics)) return NvStatus::InvalidSize; @@ -84,12 +84,12 @@ namespace skyline::service::nvdrv::device { return NvStatus::Success; } - NvStatus NvHostCtrlGpu::GetTpcMasks(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostCtrlGpu::GetTpcMasks(IoctlType type, span buffer, span inlineBuffer) { struct Data { u32 maskBufSize; // In u32 reserved[3]; // In u64 maskBuf; // Out - } &data = util::As(buffer); + } &data = buffer.as(); if (data.maskBufSize) data.maskBuf = 0x3; @@ -97,12 +97,12 @@ namespace skyline::service::nvdrv::device { return NvStatus::Success; } - NvStatus NvHostCtrlGpu::GetActiveSlotMask(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvHostCtrlGpu::GetActiveSlotMask(IoctlType type, span buffer, span inlineBuffer) { struct Data { u32 slot{0x07}; // Out u32 mask{0x01}; // Out } data; - util::As(buffer) = data; + buffer.as() = data; return NvStatus::Success; } diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.h index 5ea34863..26670d0c 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.h @@ -20,27 +20,27 @@ namespace skyline::service::nvdrv::device { /** * @brief This returns a u32 GPU ZCULL Context Size (https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_ZCULL_GET_CTX_SIZE) */ - NvStatus ZCullGetCtxSize(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus ZCullGetCtxSize(IoctlType type, span buffer, span inlineBuffer); /** * @brief This returns a the GPU ZCULL Information (https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_ZCULL_GET_INFO) */ - NvStatus ZCullGetInfo(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus ZCullGetInfo(IoctlType type, span buffer, span inlineBuffer); /** * @brief This returns a struct with certain GPU characteristics (https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_GET_CHARACTERISTICS) */ - NvStatus GetCharacteristics(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus GetCharacteristics(IoctlType type, span buffer, span inlineBuffer); /** * @brief This returns the TPC mask value for each GPC (https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_GET_TPC_MASKS) */ - NvStatus GetTpcMasks(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus GetTpcMasks(IoctlType type, span buffer, span inlineBuffer); /** * @brief This returns the mask value for a ZBC slot (https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_ZBC_GET_ACTIVE_SLOT_MASK) */ - NvStatus GetActiveSlotMask(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus GetActiveSlotMask(IoctlType type, span buffer, span inlineBuffer); std::shared_ptr QueryEvent(u32 eventId); diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp index bad99df3..2571090e 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp @@ -9,11 +9,11 @@ namespace skyline::service::nvdrv::device { NvMap::NvMap(const DeviceState &state) : NvDevice(state) {} - NvStatus NvMap::Create(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvMap::Create(IoctlType type, span buffer, span inlineBuffer) { struct Data { u32 size; // In u32 handle; // Out - } &data = util::As(buffer); + } &data = buffer.as(); handleTable[handleIndex] = std::make_shared(idIndex++, data.size); data.handle = handleIndex++; @@ -22,11 +22,11 @@ namespace skyline::service::nvdrv::device { return NvStatus::Success; } - NvStatus NvMap::FromId(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvMap::FromId(IoctlType type, span buffer, span inlineBuffer) { struct Data { u32 id; // In u32 handle; // Out - } &data = util::As(buffer); + } &data = buffer.as(); for (const auto &object : handleTable) { if (object.second->id == data.id) { @@ -40,7 +40,7 @@ namespace skyline::service::nvdrv::device { return NvStatus::BadValue; } - NvStatus NvMap::Alloc(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvMap::Alloc(IoctlType type, span buffer, span inlineBuffer) { struct Data { u32 handle; // In u32 heapMask; // In @@ -49,7 +49,7 @@ namespace skyline::service::nvdrv::device { u8 kind; // In u8 _pad0_[7]; u64 address; // InOut - } &data = util::As(buffer); + } &data = buffer.as(); try { auto &object = handleTable.at(data.handle); @@ -68,14 +68,14 @@ namespace skyline::service::nvdrv::device { } } - NvStatus NvMap::Free(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvMap::Free(IoctlType type, span buffer, span inlineBuffer) { struct Data { u32 handle; // In u32 _pad0_; u64 address; // Out u32 size; // Out u32 flags; // Out - } &data = util::As(buffer); + } &data = buffer.as(); try { const auto &object = handleTable.at(data.handle); @@ -98,13 +98,13 @@ namespace skyline::service::nvdrv::device { } } - NvStatus NvMap::Param(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvMap::Param(IoctlType type, span buffer, span inlineBuffer) { enum class Parameter : u32 { Size = 1, Alignment = 2, Base = 3, HeapMask = 4, Kind = 5, Compr = 6 }; // https://android.googlesource.com/kernel/tegra/+/refs/heads/android-tegra-flounder-3.10-marshmallow/include/linux/nvmap.h#102 struct Data { u32 handle; // In Parameter parameter; // In u32 result; // Out - } &data = util::As(buffer); + } &data = buffer.as(); try { auto &object = handleTable.at(data.handle); @@ -143,11 +143,11 @@ namespace skyline::service::nvdrv::device { } } - NvStatus NvMap::GetId(IoctlType type, std::span buffer, std::span inlineBuffer) { + NvStatus NvMap::GetId(IoctlType type, span buffer, span inlineBuffer) { struct Data { u32 id; // Out u32 handle; // In - } &data = util::As(buffer); + } &data = buffer.as(); try { data.id = handleTable.at(data.handle)->id; diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.h index 0448a3c4..0883b882 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.h @@ -44,32 +44,32 @@ namespace skyline::service::nvdrv::device { /** * @brief This creates an NvMapObject and returns an handle to it (https://switchbrew.org/wiki/NV_services#NVMAP_IOC_CREATE) */ - NvStatus Create(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus Create(IoctlType type, span buffer, span inlineBuffer); /** * @brief This returns the handle of an NvMapObject from it's ID (https://switchbrew.org/wiki/NV_services#NVMAP_IOC_FROM_ID) */ - NvStatus FromId(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus FromId(IoctlType type, span buffer, span inlineBuffer); /** * @brief This allocates memory for an NvMapObject (https://switchbrew.org/wiki/NV_services#NVMAP_IOC_ALLOC) */ - NvStatus Alloc(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus Alloc(IoctlType type, span buffer, span inlineBuffer); /** * @brief This frees previously allocated memory (https://switchbrew.org/wiki/NV_services#NVMAP_IOC_FREE) */ - NvStatus Free(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus Free(IoctlType type, span buffer, span inlineBuffer); /** * @brief This returns a particular parameter from an NvMapObject (https://switchbrew.org/wiki/NV_services#NVMAP_IOC_PARAM) */ - NvStatus Param(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus Param(IoctlType type, span buffer, span inlineBuffer); /** * @brief This returns the ID of an NvMapObject from it's handle (https://switchbrew.org/wiki/NV_services#NVMAP_IOC_GET_ID) */ - NvStatus GetId(IoctlType type, std::span buffer, std::span inlineBuffer); + NvStatus GetId(IoctlType type, span buffer, span inlineBuffer); NVDEVICE_DECL( NVFUNC(0x0101, NvMap, Create), diff --git a/app/src/main/cpp/skyline/services/nvdrv/driver.cpp b/app/src/main/cpp/skyline/services/nvdrv/driver.cpp index 505d4516..f5740bc7 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/driver.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/driver.cpp @@ -11,7 +11,7 @@ namespace skyline::service::nvdrv { Driver::Driver(const DeviceState &state) : state(state), hostSyncpoint(state) {} - u32 Driver::OpenDevice(const std::string &path) { + u32 Driver::OpenDevice(std::string_view path) { state.logger->Debug("Opening NVDRV device ({}): {}", fdIndex, path); switch (util::Hash(path)) { diff --git a/app/src/main/cpp/skyline/services/nvdrv/driver.h b/app/src/main/cpp/skyline/services/nvdrv/driver.h index 880e6eb6..80798b64 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/driver.h +++ b/app/src/main/cpp/skyline/services/nvdrv/driver.h @@ -46,7 +46,7 @@ namespace skyline::service::nvdrv { * @param path The path of the device to open an FD to * @return The file descriptor to the device */ - u32 OpenDevice(const std::string &path); + u32 OpenDevice(std::string_view path); /** * @brief Returns a particular device with a specific FD diff --git a/app/src/main/cpp/skyline/services/pl/IPlatformServiceManager.cpp b/app/src/main/cpp/skyline/services/pl/IPlatformServiceManager.cpp index 6cf6c618..ce4b0fa5 100644 --- a/app/src/main/cpp/skyline/services/pl/IPlatformServiceManager.cpp +++ b/app/src/main/cpp/skyline/services/pl/IPlatformServiceManager.cpp @@ -40,7 +40,7 @@ namespace skyline::service::pl { *pointer++ = font.length ^ SharedFontKey; font.offset = reinterpret_cast(pointer) - fontSharedMem->kernel.address; - memcpy(pointer, font.data, font.length); + std::memcpy(pointer, font.data, font.length); pointer = reinterpret_cast(reinterpret_cast(pointer) + font.length); } } diff --git a/app/src/main/cpp/skyline/services/settings/ISettingsServer.cpp b/app/src/main/cpp/skyline/services/settings/ISettingsServer.cpp index 7fbe87a7..70d3d44b 100644 --- a/app/src/main/cpp/skyline/services/settings/ISettingsServer.cpp +++ b/app/src/main/cpp/skyline/services/settings/ISettingsServer.cpp @@ -7,7 +7,7 @@ namespace skyline::service::settings { ISettingsServer::ISettingsServer(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {} - constexpr std::array LanguageCodeList = { + constexpr std::array LanguageCodeList{ util::MakeMagic("ja"), util::MakeMagic("en-US"), util::MakeMagic("fr"), @@ -28,8 +28,7 @@ namespace skyline::service::settings { }; Result ISettingsServer::GetAvailableLanguageCodes(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - state.process->WriteMemory(LanguageCodeList.data(), request.outputBuf.at(0).address, constant::OldLanguageCodeListSize * sizeof(u64)); - + request.outputBuf.at(0).copy_from(span(LanguageCodeList).first(constant::OldLanguageCodeListSize)); response.Push(constant::OldLanguageCodeListSize); return {}; } @@ -40,8 +39,7 @@ namespace skyline::service::settings { } Result ISettingsServer::GetAvailableLanguageCodes2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - state.process->WriteMemory(LanguageCodeList.data(), request.outputBuf.at(0).address, constant::NewLanguageCodeListSize * sizeof(u64)); - + request.outputBuf.at(0).copy_from(LanguageCodeList); response.Push(constant::NewLanguageCodeListSize); return {}; } diff --git a/app/src/main/cpp/skyline/services/settings/ISystemSettingsServer.cpp b/app/src/main/cpp/skyline/services/settings/ISystemSettingsServer.cpp index 8f7261aa..ebe29347 100644 --- a/app/src/main/cpp/skyline/services/settings/ISystemSettingsServer.cpp +++ b/app/src/main/cpp/skyline/services/settings/ISystemSettingsServer.cpp @@ -8,8 +8,7 @@ namespace skyline::service::settings { ISystemSettingsServer::ISystemSettingsServer(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {} Result ISystemSettingsServer::GetFirmwareVersion(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { - SysVerTitle title{.major=9, .minor=0, .micro=0, .revMajor=4, .revMinor=0, .platform="NX", .verHash="4de65c071fd0869695b7629f75eb97b2551dbf2f", .dispVer="9.0.0", .dispTitle="NintendoSDK Firmware for NX 9.0.0-4.0"}; - state.process->WriteMemory(title, request.outputBuf.at(0).address); + request.outputBuf.at(0).as() = {.major=9, .minor=0, .micro=0, .revMajor=4, .revMinor=0, .platform="NX", .verHash="4de65c071fd0869695b7629f75eb97b2551dbf2f", .dispVer="9.0.0", .dispTitle="NintendoSDK Firmware for NX 9.0.0-4.0"}; return {}; } }