mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-29 14:54:16 +01:00
Address a bunch of issues detected by clang-tidy
This commit is contained in:
parent
9d5138bef1
commit
48acb6d369
@ -5,7 +5,7 @@
|
|||||||
#include "adpcm_decoder.h"
|
#include "adpcm_decoder.h"
|
||||||
|
|
||||||
namespace skyline::audio {
|
namespace skyline::audio {
|
||||||
AdpcmDecoder::AdpcmDecoder(const std::vector<std::array<i16, 2>> &coefficients) : coefficients(coefficients) {}
|
AdpcmDecoder::AdpcmDecoder(std::vector<std::array<i16, 2>> coefficients) : coefficients(std::move(coefficients)) {}
|
||||||
|
|
||||||
std::vector<i16> AdpcmDecoder::Decode(span<u8> adpcmData) {
|
std::vector<i16> AdpcmDecoder::Decode(span<u8> adpcmData) {
|
||||||
constexpr size_t BytesPerFrame{0x8};
|
constexpr size_t BytesPerFrame{0x8};
|
||||||
|
@ -26,7 +26,7 @@ namespace skyline::audio {
|
|||||||
std::vector<std::array<i16, 2>> coefficients; //!< The coefficients for decoding the ADPCM stream
|
std::vector<std::array<i16, 2>> coefficients; //!< The coefficients for decoding the ADPCM stream
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AdpcmDecoder(const std::vector<std::array<i16, 2>> &coefficients);
|
AdpcmDecoder(std::vector<std::array<i16, 2>> coefficients);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Decodes a buffer of ADPCM data into I16 PCM
|
* @brief Decodes a buffer of ADPCM data into I16 PCM
|
||||||
|
@ -12,7 +12,7 @@ namespace skyline {
|
|||||||
constexpr u8 ChannelCount{2}; //!< The common amount of channels to use for audio output
|
constexpr u8 ChannelCount{2}; //!< The common amount of channels to use for audio output
|
||||||
constexpr u16 MixBufferSize{960}; //!< The size of the mix buffer by default
|
constexpr u16 MixBufferSize{960}; //!< The size of the mix buffer by default
|
||||||
constexpr auto PcmFormat{oboe::AudioFormat::I16}; //!< The common PCM data format to use for audio output
|
constexpr auto PcmFormat{oboe::AudioFormat::I16}; //!< The common PCM data format to use for audio output
|
||||||
};
|
}
|
||||||
|
|
||||||
namespace audio {
|
namespace audio {
|
||||||
enum class AudioFormat : u8 {
|
enum class AudioFormat : u8 {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "track.h"
|
#include "track.h"
|
||||||
|
|
||||||
namespace skyline::audio {
|
namespace skyline::audio {
|
||||||
AudioTrack::AudioTrack(u8 channelCount, u32 sampleRate, const std::function<void()> &releaseCallback) : channelCount(channelCount), sampleRate(sampleRate), releaseCallback(releaseCallback) {
|
AudioTrack::AudioTrack(u8 channelCount, u32 sampleRate, std::function<void()> releaseCallback) : channelCount(channelCount), sampleRate(sampleRate), releaseCallback(std::move(releaseCallback)) {
|
||||||
if (sampleRate != constant::SampleRate)
|
if (sampleRate != constant::SampleRate)
|
||||||
throw exception("Unsupported audio sample rate: {}", sampleRate);
|
throw exception("Unsupported audio sample rate: {}", sampleRate);
|
||||||
|
|
||||||
|
@ -31,12 +31,12 @@ namespace skyline::audio {
|
|||||||
* @param sampleRate The sample rate to use for the track
|
* @param sampleRate The sample rate to use for the track
|
||||||
* @param releaseCallback A callback to call when a buffer has been played
|
* @param releaseCallback A callback to call when a buffer has been played
|
||||||
*/
|
*/
|
||||||
AudioTrack(u8 channelCount, u32 sampleRate, const std::function<void()> &releaseCallback);
|
AudioTrack(u8 channelCount, u32 sampleRate, std::function<void()> releaseCallback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts audio playback using data from appended buffers
|
* @brief Starts audio playback using data from appended buffers
|
||||||
*/
|
*/
|
||||||
inline void Start() {
|
void Start() {
|
||||||
playbackState = AudioOutState::Started;
|
playbackState = AudioOutState::Started;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ namespace skyline {
|
|||||||
logFile << "\0360\035" << str << '\n';
|
logFile << "\0360\035" << str << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::Write(LogLevel level, const std::string& str) {
|
void Logger::Write(LogLevel level, const std::string &str) {
|
||||||
constexpr std::array<char, 5> levelCharacter{'E', 'W', 'I', 'D', 'V'}; // The LogLevel as written out to a file
|
constexpr std::array<char, 5> levelCharacter{'E', 'W', 'I', 'D', 'V'}; // The LogLevel as written out to a file
|
||||||
constexpr std::array<int, 5> levelAlog{ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE}; // This corresponds to LogLevel and provides its equivalent for NDK Logging
|
constexpr std::array<int, 5> levelAlog{ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE}; // This corresponds to LogLevel and provides its equivalent for NDK Logging
|
||||||
|
|
||||||
|
@ -73,10 +73,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
Result() = default;
|
Result() = default;
|
||||||
|
|
||||||
constexpr Result(u16 module, u16 id) {
|
constexpr Result(u16 module, u16 id) : module(module), id(id) {}
|
||||||
this->module = module;
|
|
||||||
this->id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr operator u32() const {
|
constexpr operator u32() const {
|
||||||
return raw;
|
return raw;
|
||||||
@ -121,7 +118,7 @@ namespace skyline {
|
|||||||
* @param args The arguments based on format_str
|
* @param args The arguments based on format_str
|
||||||
*/
|
*/
|
||||||
template<typename S, typename... Args>
|
template<typename S, typename... Args>
|
||||||
inline exception(const S &formatStr, Args &&... args) : runtime_error(fmt::format(formatStr, util::FmtCast(args)...)) {}
|
exception(const S &formatStr, Args &&... args) : runtime_error(fmt::format(formatStr, util::FmtCast(args)...)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
@ -434,31 +431,31 @@ namespace skyline {
|
|||||||
void Write(LogLevel level, const std::string &str);
|
void Write(LogLevel level, const std::string &str);
|
||||||
|
|
||||||
template<typename S, typename... Args>
|
template<typename S, typename... Args>
|
||||||
inline void Error(const S &formatStr, Args &&... args) {
|
void Error(const S &formatStr, Args &&... args) {
|
||||||
if (LogLevel::Error <= configLevel)
|
if (LogLevel::Error <= configLevel)
|
||||||
Write(LogLevel::Error, fmt::format(formatStr, util::FmtCast(args)...));
|
Write(LogLevel::Error, fmt::format(formatStr, util::FmtCast(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename S, typename... Args>
|
template<typename S, typename... Args>
|
||||||
inline void Warn(const S &formatStr, Args &&... args) {
|
void Warn(const S &formatStr, Args &&... args) {
|
||||||
if (LogLevel::Warn <= configLevel)
|
if (LogLevel::Warn <= configLevel)
|
||||||
Write(LogLevel::Warn, fmt::format(formatStr, util::FmtCast(args)...));
|
Write(LogLevel::Warn, fmt::format(formatStr, util::FmtCast(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename S, typename... Args>
|
template<typename S, typename... Args>
|
||||||
inline void Info(const S &formatStr, Args &&... args) {
|
void Info(const S &formatStr, Args &&... args) {
|
||||||
if (LogLevel::Info <= configLevel)
|
if (LogLevel::Info <= configLevel)
|
||||||
Write(LogLevel::Info, fmt::format(formatStr, util::FmtCast(args)...));
|
Write(LogLevel::Info, fmt::format(formatStr, util::FmtCast(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename S, typename... Args>
|
template<typename S, typename... Args>
|
||||||
inline void Debug(const S &formatStr, Args &&... args) {
|
void Debug(const S &formatStr, Args &&... args) {
|
||||||
if (LogLevel::Debug <= configLevel)
|
if (LogLevel::Debug <= configLevel)
|
||||||
Write(LogLevel::Debug, fmt::format(formatStr, util::FmtCast(args)...));
|
Write(LogLevel::Debug, fmt::format(formatStr, util::FmtCast(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename S, typename... Args>
|
template<typename S, typename... Args>
|
||||||
inline void Verbose(const S &formatStr, Args &&... args) {
|
void Verbose(const S &formatStr, Args &&... args) {
|
||||||
if (LogLevel::Verbose <= configLevel)
|
if (LogLevel::Verbose <= configLevel)
|
||||||
Write(LogLevel::Verbose, fmt::format(formatStr, util::FmtCast(args)...));
|
Write(LogLevel::Verbose, fmt::format(formatStr, util::FmtCast(args)...));
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ namespace skyline {
|
|||||||
* @param copyOffset The offset into the buffer after which to use memcpy rather than copyFunction, -1 will use it for the entire buffer
|
* @param copyOffset The offset into the buffer after which to use memcpy rather than copyFunction, -1 will use it for the entire buffer
|
||||||
* @return The amount of data written into the input buffer in units of Type
|
* @return The amount of data written into the input buffer in units of Type
|
||||||
*/
|
*/
|
||||||
inline size_t Read(span <Type> buffer, void copyFunction(Type *, Type *) = {}, ssize_t copyOffset = -1) {
|
size_t Read(span <Type> buffer, void copyFunction(Type *, Type *) = {}, ssize_t copyOffset = -1) {
|
||||||
std::lock_guard guard(mtx);
|
std::lock_guard guard(mtx);
|
||||||
|
|
||||||
if (empty)
|
if (empty)
|
||||||
@ -91,7 +91,7 @@ namespace skyline {
|
|||||||
/**
|
/**
|
||||||
* @brief Appends data from the specified buffer into this buffer
|
* @brief Appends data from the specified buffer into this buffer
|
||||||
*/
|
*/
|
||||||
inline void Append(span <Type> buffer) {
|
void Append(span <Type> buffer) {
|
||||||
std::lock_guard guard(mtx);
|
std::lock_guard guard(mtx);
|
||||||
|
|
||||||
Type *pointer{buffer.data()};
|
Type *pointer{buffer.data()};
|
||||||
|
@ -24,19 +24,19 @@ namespace skyline {
|
|||||||
/**
|
/**
|
||||||
* @note The internal allocation is an item larger as we require a sentinel value
|
* @note The internal allocation is an item larger as we require a sentinel value
|
||||||
*/
|
*/
|
||||||
inline CircularQueue(size_t size) : vector((size + 1) * sizeof(Type)) {}
|
CircularQueue(size_t size) : vector((size + 1) * sizeof(Type)) {}
|
||||||
|
|
||||||
inline CircularQueue(const CircularQueue &) = delete;
|
CircularQueue(const CircularQueue &) = delete;
|
||||||
|
|
||||||
inline CircularQueue &operator=(const CircularQueue &) = delete;
|
CircularQueue &operator=(const CircularQueue &) = delete;
|
||||||
|
|
||||||
inline CircularQueue(CircularQueue &&other) : vector(std::move(other.vector)), consumptionMutex(std::move(other.consumptionMutex)), consumeCondition(std::move(other.consumeCondition)), productionMutex(std::move(other.productionMutex)), produceCondition(std::move(other.produceCondition)) {
|
CircularQueue(CircularQueue &&other) : vector(std::move(other.vector)), consumptionMutex(std::move(other.consumptionMutex)), consumeCondition(std::move(other.consumeCondition)), productionMutex(std::move(other.productionMutex)), produceCondition(std::move(other.produceCondition)) {
|
||||||
this->start = other.start;
|
start = other.start;
|
||||||
this->end = other.end;
|
end = other.end;
|
||||||
other.start = other.end = nullptr;
|
other.start = other.end = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ~CircularQueue() {
|
~CircularQueue() {
|
||||||
while (start != end) {
|
while (start != end) {
|
||||||
auto next{start + 1};
|
auto next{start + 1};
|
||||||
next = (next == reinterpret_cast<Type *>(vector.end().base())) ? reinterpret_cast<Type *>(vector.begin().base()) : next;
|
next = (next == reinterpret_cast<Type *>(vector.end().base())) ? reinterpret_cast<Type *>(vector.begin().base()) : next;
|
||||||
@ -50,7 +50,7 @@ namespace skyline {
|
|||||||
* @param function A function that is called for each item (with the only parameter as a reference to that item)
|
* @param function A function that is called for each item (with the only parameter as a reference to that item)
|
||||||
*/
|
*/
|
||||||
template<typename F>
|
template<typename F>
|
||||||
[[noreturn]] inline void Process(F function) {
|
[[noreturn]] void Process(F function) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (start == end) {
|
if (start == end) {
|
||||||
std::unique_lock lock(productionMutex);
|
std::unique_lock lock(productionMutex);
|
||||||
@ -68,7 +68,7 @@ namespace skyline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Push(const Type &item) {
|
void Push(const Type &item) {
|
||||||
std::unique_lock lock(productionMutex);
|
std::unique_lock lock(productionMutex);
|
||||||
end = (end == reinterpret_cast<Type *>(vector.end().base()) - 1) ? reinterpret_cast<Type *>(vector.begin().base()) : end;
|
end = (end == reinterpret_cast<Type *>(vector.end().base()) - 1) ? reinterpret_cast<Type *>(vector.begin().base()) : end;
|
||||||
if (start == end + 1) {
|
if (start == end + 1) {
|
||||||
@ -79,7 +79,7 @@ namespace skyline {
|
|||||||
produceCondition.notify_one();
|
produceCondition.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Append(span <Type> buffer) {
|
void Append(span <Type> buffer) {
|
||||||
std::unique_lock lock(productionMutex);
|
std::unique_lock lock(productionMutex);
|
||||||
for (const auto &item : buffer) {
|
for (const auto &item : buffer) {
|
||||||
auto next{end + 1};
|
auto next{end + 1};
|
||||||
@ -99,7 +99,7 @@ namespace skyline {
|
|||||||
* @param tranformation A function that takes in an item of TransformedType as input and returns an item of Type
|
* @param tranformation A function that takes in an item of TransformedType as input and returns an item of Type
|
||||||
*/
|
*/
|
||||||
template<typename TransformedType, typename Transformation>
|
template<typename TransformedType, typename Transformation>
|
||||||
inline void AppendTranform(span <TransformedType> buffer, Transformation transformation) {
|
void AppendTranform(span <TransformedType> buffer, Transformation transformation) {
|
||||||
std::unique_lock lock(productionMutex);
|
std::unique_lock lock(productionMutex);
|
||||||
for (const auto &item : buffer) {
|
for (const auto &item : buffer) {
|
||||||
auto next{end + 1};
|
auto next{end + 1};
|
||||||
|
@ -49,7 +49,7 @@ namespace skyline::signal {
|
|||||||
void *fault{};
|
void *fault{};
|
||||||
std::vector<void *> frames; //!< A vector of all stack frame entries prior to the signal occuring
|
std::vector<void *> frames; //!< A vector of all stack frame entries prior to the signal occuring
|
||||||
|
|
||||||
inline std::string what() const {
|
std::string what() const {
|
||||||
if (!fault)
|
if (!fault)
|
||||||
return fmt::format("Signal: {} (PC: 0x{:X})", strsignal(signal), reinterpret_cast<uintptr_t>(pc));
|
return fmt::format("Signal: {} (PC: 0x{:X})", strsignal(signal), reinterpret_cast<uintptr_t>(pc));
|
||||||
else
|
else
|
||||||
|
@ -19,7 +19,7 @@ namespace skyline::crypto {
|
|||||||
/**
|
/**
|
||||||
* @brief Calculates IV for XTS, basically just big to little endian conversion
|
* @brief Calculates IV for XTS, basically just big to little endian conversion
|
||||||
*/
|
*/
|
||||||
inline static std::array<u8, 0x10> GetTweak(size_t sector) {
|
static std::array<u8, 0x10> GetTweak(size_t sector) {
|
||||||
std::array<u8, 0x10> tweak{};
|
std::array<u8, 0x10> tweak{};
|
||||||
size_t le{__builtin_bswap64(sector)};
|
size_t le{__builtin_bswap64(sector)};
|
||||||
std::memcpy(tweak.data() + 8, &le, 8);
|
std::memcpy(tweak.data() + 8, &le, 8);
|
||||||
@ -45,7 +45,7 @@ namespace skyline::crypto {
|
|||||||
/**
|
/**
|
||||||
* @brief Decrypts the supplied data in-place
|
* @brief Decrypts the supplied data in-place
|
||||||
*/
|
*/
|
||||||
inline void Decrypt(span<u8> data) {
|
void Decrypt(span<u8> data) {
|
||||||
Decrypt(data.data(), data.data(), data.size());
|
Decrypt(data.data(), data.data(), data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ namespace skyline::crypto {
|
|||||||
/**
|
/**
|
||||||
* @brief Decrypts data with XTS and writes back to it
|
* @brief Decrypts data with XTS and writes back to it
|
||||||
*/
|
*/
|
||||||
inline void XtsDecrypt(span<u8> data, size_t sector, size_t sectorSize) {
|
void XtsDecrypt(span<u8> data, size_t sector, size_t sectorSize) {
|
||||||
XtsDecrypt(data.data(), data.data(), data.size(), sector, sectorSize);
|
XtsDecrypt(data.data(), data.data(), data.size(), sector, sectorSize);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -35,7 +35,7 @@ namespace skyline::crypto {
|
|||||||
void KeyStore::PopulateTitleKeys(std::string_view keyName, std::string_view value) {
|
void KeyStore::PopulateTitleKeys(std::string_view keyName, std::string_view value) {
|
||||||
Key128 key{util::HexStringToArray<16>(keyName)};
|
Key128 key{util::HexStringToArray<16>(keyName)};
|
||||||
Key128 valueArray{util::HexStringToArray<16>(value)};
|
Key128 valueArray{util::HexStringToArray<16>(value)};
|
||||||
titleKeys.insert({std::move(key), std::move(valueArray)});
|
titleKeys.emplace(key, valueArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyStore::PopulateKeys(std::string_view keyName, std::string_view value) {
|
void KeyStore::PopulateKeys(std::string_view keyName, std::string_view value) {
|
||||||
|
@ -47,7 +47,7 @@ namespace skyline::crypto {
|
|||||||
void PopulateKeys(std::string_view keyName, std::string_view value);
|
void PopulateKeys(std::string_view keyName, std::string_view value);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline std::optional<Key128> GetTitleKey(const Key128 &title) {
|
std::optional<Key128> GetTitleKey(const Key128 &title) {
|
||||||
auto it{titleKeys.find(title)};
|
auto it{titleKeys.find(title)};
|
||||||
if (it == titleKeys.end())
|
if (it == titleKeys.end())
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -27,6 +27,6 @@ namespace skyline::gpu {
|
|||||||
std::array<Syncpoint, constant::MaxHwSyncpointCount> syncpoints{};
|
std::array<Syncpoint, constant::MaxHwSyncpointCount> syncpoints{};
|
||||||
gpfifo::GPFIFO gpfifo;
|
gpfifo::GPFIFO gpfifo;
|
||||||
|
|
||||||
inline GPU(const DeviceState &state) : state(state), presentation(state), memoryManager(state), gpfifo(state), fermi2D(std::make_shared<engine::Engine>(state)), keplerMemory(std::make_shared<engine::Engine>(state)), maxwell3D(std::make_shared<engine::Maxwell3D>(state)), maxwellCompute(std::make_shared<engine::Engine>(state)), maxwellDma(std::make_shared<engine::Engine>(state)) {}
|
GPU(const DeviceState &state) : state(state), presentation(state), memoryManager(state), gpfifo(state), fermi2D(std::make_shared<engine::Engine>(state)), keplerMemory(std::make_shared<engine::Engine>(state)), maxwell3D(std::make_shared<engine::Maxwell3D>(state)), maxwellCompute(std::make_shared<engine::Engine>(state)), maxwellDma(std::make_shared<engine::Engine>(state)) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ namespace skyline {
|
|||||||
public:
|
public:
|
||||||
GPFIFO(const DeviceState &state) : Engine(state) {}
|
GPFIFO(const DeviceState &state) : Engine(state) {}
|
||||||
|
|
||||||
void CallMethod(MethodParams params) {
|
void CallMethod(MethodParams params) override {
|
||||||
state.logger->Debug("Called method in GPFIFO: 0x{:X} args: 0x{:X}", params.method, params.argument);
|
state.logger->Debug("Called method in GPFIFO: 0x{:X} args: 0x{:X}", params.method, params.argument);
|
||||||
|
|
||||||
registers.raw[params.method] = params.argument;
|
registers.raw[params.method] = params.argument;
|
||||||
|
@ -569,7 +569,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
void ResetRegs();
|
void ResetRegs();
|
||||||
|
|
||||||
void CallMethod(MethodParams params);
|
void CallMethod(MethodParams params) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,8 @@ namespace skyline::gpu {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
throw exception("Unknown MME opcode encountered: 0x{:X}", static_cast<u8>(opcode->operation));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcode->exit && (delayedOpcode == nullptr)) {
|
if (opcode->exit && (delayedOpcode == nullptr)) {
|
||||||
|
@ -124,7 +124,7 @@ namespace skyline::gpu::vmm {
|
|||||||
|
|
||||||
u64 MemoryManager::MapFixed(u64 virtAddr, u8 *cpuPtr, u64 size) {
|
u64 MemoryManager::MapFixed(u64 virtAddr, u8 *cpuPtr, u64 size) {
|
||||||
if (!util::IsAligned(virtAddr, constant::GpuPageSize))
|
if (!util::IsAligned(virtAddr, constant::GpuPageSize))
|
||||||
return false;
|
return 0;
|
||||||
|
|
||||||
size = util::AlignUp(size, constant::GpuPageSize);
|
size = util::AlignUp(size, constant::GpuPageSize);
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ namespace skyline {
|
|||||||
* @return If the given chunk can be contained wholly within this chunk
|
* @return If the given chunk can be contained wholly within this chunk
|
||||||
*/
|
*/
|
||||||
inline bool CanContain(const ChunkDescriptor &chunk) {
|
inline bool CanContain(const ChunkDescriptor &chunk) {
|
||||||
return (chunk.virtAddr >= this->virtAddr) && ((this->size + this->virtAddr) >= (chunk.size + chunk.virtAddr));
|
return (chunk.virtAddr >= virtAddr) && ((size + virtAddr) >= (chunk.size + chunk.virtAddr));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ namespace skyline::gpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard guard(waiterLock);
|
std::lock_guard guard(waiterLock);
|
||||||
waiterMap.insert({nextWaiterId, Waiter{threshold, callback}});
|
waiterMap.emplace(nextWaiterId, Waiter{threshold, callback});
|
||||||
|
|
||||||
return nextWaiterId++;
|
return nextWaiterId++;
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ namespace skyline::gpu {
|
|||||||
std::condition_variable cv;
|
std::condition_variable cv;
|
||||||
bool flag{};
|
bool flag{};
|
||||||
|
|
||||||
if (timeout == timeout.max())
|
if (timeout == std::chrono::steady_clock::duration::max())
|
||||||
timeout = std::chrono::seconds(1);
|
timeout = std::chrono::seconds(1);
|
||||||
|
|
||||||
if (!RegisterWaiter(threshold, [&cv, &mtx, &flag] {
|
if (!RegisterWaiter(threshold, [&cv, &mtx, &flag] {
|
||||||
@ -57,5 +57,5 @@ namespace skyline::gpu {
|
|||||||
std::unique_lock lock(mtx);
|
std::unique_lock lock(mtx);
|
||||||
return cv.wait_for(lock, timeout, [&flag] { return flag; });
|
return cv.wait_for(lock, timeout, [&flag] { return flag; });
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
@ -9,15 +9,15 @@
|
|||||||
namespace skyline::gpu {
|
namespace skyline::gpu {
|
||||||
GuestTexture::GuestTexture(const DeviceState &state, u8 *pointer, texture::Dimensions dimensions, texture::Format format, texture::TileMode tiling, texture::TileConfig layout) : state(state), pointer(pointer), dimensions(dimensions), format(format), tileMode(tiling), tileConfig(layout) {}
|
GuestTexture::GuestTexture(const DeviceState &state, u8 *pointer, texture::Dimensions dimensions, texture::Format format, texture::TileMode tiling, texture::TileConfig layout) : state(state), pointer(pointer), dimensions(dimensions), format(format), tileMode(tiling), tileConfig(layout) {}
|
||||||
|
|
||||||
std::shared_ptr<Texture> GuestTexture::InitializeTexture(std::optional<texture::Format> format, std::optional<texture::Dimensions> dimensions, texture::Swizzle swizzle) {
|
std::shared_ptr<Texture> GuestTexture::InitializeTexture(std::optional<texture::Format> pFormat, std::optional<texture::Dimensions> pDimensions, texture::Swizzle swizzle) {
|
||||||
if (!host.expired())
|
if (!host.expired())
|
||||||
throw exception("Trying to create multiple Texture objects from a single GuestTexture");
|
throw exception("Trying to create multiple Texture objects from a single GuestTexture");
|
||||||
auto sharedHost{std::make_shared<Texture>(state, shared_from_this(), dimensions ? *dimensions : this->dimensions, format ? *format : this->format, swizzle)};
|
auto sharedHost{std::make_shared<Texture>(state, shared_from_this(), pDimensions ? *pDimensions : dimensions, pFormat ? *pFormat : format, swizzle)};
|
||||||
host = sharedHost;
|
host = sharedHost;
|
||||||
return sharedHost;
|
return sharedHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(const DeviceState &state, std::shared_ptr<GuestTexture> guest, texture::Dimensions dimensions, texture::Format format, texture::Swizzle swizzle) : state(state), guest(guest), dimensions(dimensions), format(format), swizzle(swizzle) {
|
Texture::Texture(const DeviceState &state, std::shared_ptr<GuestTexture> guest, texture::Dimensions dimensions, texture::Format format, texture::Swizzle swizzle) : state(state), guest(std::move(guest)), dimensions(dimensions), format(format), swizzle(swizzle) {
|
||||||
SynchronizeHost();
|
SynchronizeHost();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ namespace skyline::gpu {
|
|||||||
auto pointer{guest->pointer};
|
auto pointer{guest->pointer};
|
||||||
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{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
|
||||||
|
@ -24,6 +24,6 @@ namespace skyline::input {
|
|||||||
NpadManager npad;
|
NpadManager npad;
|
||||||
TouchManager touch;
|
TouchManager touch;
|
||||||
|
|
||||||
inline Input(const DeviceState &state) : state(state), kHid(std::make_shared<kernel::type::KSharedMemory>(state, sizeof(HidSharedMemory))), hid(reinterpret_cast<HidSharedMemory *>(kHid->kernel.ptr)), npad(state, hid), touch(state, hid) {}
|
Input(const DeviceState &state) : state(state), kHid(std::make_shared<kernel::type::KSharedMemory>(state, sizeof(HidSharedMemory))), hid(reinterpret_cast<HidSharedMemory *>(kHid->kernel.ptr)), npad(state, hid), touch(state, hid) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -89,9 +89,10 @@ namespace skyline::input {
|
|||||||
return NpadControllerType::JoyconLeft;
|
return NpadControllerType::JoyconLeft;
|
||||||
case 7:
|
case 7:
|
||||||
return NpadControllerType::JoyconRight;
|
return NpadControllerType::JoyconRight;
|
||||||
}
|
default:
|
||||||
return NpadControllerType::None;
|
return NpadControllerType::None;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,11 +147,11 @@ namespace skyline::input {
|
|||||||
|
|
||||||
NpadDevice(NpadManager &manager, NpadSection §ion, NpadId id);
|
NpadDevice(NpadManager &manager, NpadSection §ion, NpadId id);
|
||||||
|
|
||||||
inline void SetAssignment(NpadJoyAssignment assignment) {
|
void SetAssignment(NpadJoyAssignment assignment) {
|
||||||
section.header.assignment = assignment;
|
section.header.assignment = assignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NpadJoyAssignment GetAssignment() {
|
NpadJoyAssignment GetAssignment() {
|
||||||
return section.header.assignment;
|
return section.header.assignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ namespace skyline {
|
|||||||
* @return The contents of the field as objectType
|
* @return The contents of the field as objectType
|
||||||
*/
|
*/
|
||||||
template<typename objectType>
|
template<typename objectType>
|
||||||
inline objectType GetField(const char *key) {
|
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"));
|
||||||
@ -53,6 +53,8 @@ namespace skyline {
|
|||||||
return env->GetFloatField(instance, env->GetFieldID(instanceClass, key, "F"));
|
return env->GetFloatField(instance, env->GetFieldID(instanceClass, key, "F"));
|
||||||
else if constexpr(std::is_same<objectType, jdouble>())
|
else if constexpr(std::is_same<objectType, jdouble>())
|
||||||
return env->GetDoubleField(instance, env->GetFieldID(instanceClass, key, "D"));
|
return env->GetDoubleField(instance, env->GetFieldID(instanceClass, key, "D"));
|
||||||
|
else
|
||||||
|
throw exception("GetField: Unhandled object type");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,19 +129,11 @@ namespace skyline {
|
|||||||
u16 size : 16; //!< The 16 bit size of the buffer
|
u16 size : 16; //!< The 16 bit size of the buffer
|
||||||
u32 address0_31 : 32; //!< The first 32-bits of the address
|
u32 address0_31 : 32; //!< The first 32-bits of the address
|
||||||
|
|
||||||
BufferDescriptorX(u64 address, u16 counter, u16 size) : size(size) {
|
u8 *Pointer() {
|
||||||
address0_31 = static_cast<u32>(address & 0x7FFFFFFF80000000);
|
|
||||||
address32_35 = static_cast<u16>(address & 0x78000000);
|
|
||||||
address36_38 = static_cast<u16>(address & 0x7000000);
|
|
||||||
counter0_5 = static_cast<u16>(address & 0x7E00);
|
|
||||||
counter9_11 = static_cast<u16>(address & 0x38);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline u8 *Pointer() {
|
|
||||||
return reinterpret_cast<u8 *>(static_cast<u64>(address0_31) | static_cast<u64>(address32_35) << 32 | static_cast<u64>(address36_38) << 36);
|
return reinterpret_cast<u8 *>(static_cast<u64>(address0_31) | static_cast<u64>(address32_35) << 32 | static_cast<u64>(address36_38) << 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u16 Counter() {
|
u16 Counter() {
|
||||||
return static_cast<u16>(counter0_5) | static_cast<u16>(counter9_11) << 9;
|
return static_cast<u16>(counter0_5) | static_cast<u16>(counter9_11) << 9;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -159,19 +151,11 @@ namespace skyline {
|
|||||||
u8 size32_35 : 4; //!< Bit 32-35 of the size
|
u8 size32_35 : 4; //!< Bit 32-35 of the size
|
||||||
u8 address32_35 : 4; //!< Bit 32-35 of the address
|
u8 address32_35 : 4; //!< Bit 32-35 of the address
|
||||||
|
|
||||||
BufferDescriptorABW(u64 address, u64 size) {
|
u8 *Pointer() {
|
||||||
address0_31 = static_cast<u32>(address & 0x7FFFFFFF80000000);
|
|
||||||
address32_35 = static_cast<u8>(address & 0x78000000);
|
|
||||||
address36_38 = static_cast<u8>(address & 0x7000000);
|
|
||||||
size0_31 = static_cast<u32>(size & 0x7FFFFFFF80000000);
|
|
||||||
size32_35 = static_cast<u8>(size & 0x78000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline u8 *Pointer() {
|
|
||||||
return reinterpret_cast<u8 *>(static_cast<u64>(address0_31) | static_cast<u64>(address32_35) << 32 | static_cast<u64>(address36_38) << 36);
|
return reinterpret_cast<u8 *>(static_cast<u64>(address0_31) | static_cast<u64>(address32_35) << 32 | static_cast<u64>(address36_38) << 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u64 Size() {
|
u64 Size() {
|
||||||
return static_cast<u64>(size0_31) | static_cast<u64>(size32_35) << 32;
|
return static_cast<u64>(size0_31) | static_cast<u64>(size32_35) << 32;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -184,11 +168,9 @@ namespace skyline {
|
|||||||
u64 address : 48; //!< The 48-bit address of the buffer
|
u64 address : 48; //!< The 48-bit address of the buffer
|
||||||
u32 size : 16; //!< The 16-bit size of the buffer
|
u32 size : 16; //!< The 16-bit size of the buffer
|
||||||
|
|
||||||
inline u8 *Pointer() {
|
u8 *Pointer() {
|
||||||
return reinterpret_cast<u8 *>(address);
|
return reinterpret_cast<u8 *>(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferDescriptorC(u64 address, u16 size) : address(address), size(size) {}
|
|
||||||
};
|
};
|
||||||
static_assert(sizeof(BufferDescriptorC) == 8);
|
static_assert(sizeof(BufferDescriptorC) == 8);
|
||||||
|
|
||||||
@ -228,7 +210,7 @@ namespace skyline {
|
|||||||
* @brief Returns a reference to an item from the top of the payload
|
* @brief Returns a reference to an item from the top of the payload
|
||||||
*/
|
*/
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
inline ValueType &Pop() {
|
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 +220,7 @@ namespace skyline {
|
|||||||
* @brief Returns a std::string_view from the payload
|
* @brief Returns a std::string_view from the payload
|
||||||
* @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) {
|
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;
|
||||||
@ -248,7 +230,7 @@ namespace skyline {
|
|||||||
* @brief Skips an object to pop off the top
|
* @brief Skips an object to pop off the top
|
||||||
*/
|
*/
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
inline void Skip() {
|
void Skip() {
|
||||||
payloadOffset += sizeof(ValueType);
|
payloadOffset += sizeof(ValueType);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -276,7 +258,7 @@ namespace skyline {
|
|||||||
* @param value A reference to the object to be written
|
* @param value A reference to the object to be written
|
||||||
*/
|
*/
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
inline void Push(const ValueType &value) {
|
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));
|
||||||
@ -286,7 +268,7 @@ namespace skyline {
|
|||||||
* @brief Writes a string to the payload
|
* @brief Writes a string to the payload
|
||||||
* @param string The string to write to the payload
|
* @param string The string to write to the payload
|
||||||
*/
|
*/
|
||||||
inline void Push(std::string_view string) {
|
void Push(std::string_view 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());
|
||||||
|
@ -61,7 +61,9 @@ namespace skyline::kernel {
|
|||||||
if (!base.address)
|
if (!base.address)
|
||||||
throw exception("Cannot find a suitable carveout for the guest address space");
|
throw exception("Cannot find a suitable carveout for the guest address space");
|
||||||
|
|
||||||
mmap(reinterpret_cast<void *>(base.address), base.size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
auto result{mmap(reinterpret_cast<void *>(base.address), base.size, PROT_NONE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)};
|
||||||
|
if (result == MAP_FAILED) [[unlikely]]
|
||||||
|
throw exception("Failed to mmap guest address space: {}", strerror(errno));
|
||||||
|
|
||||||
chunks = {
|
chunks = {
|
||||||
ChunkDescriptor{
|
ChunkDescriptor{
|
||||||
|
@ -25,7 +25,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
constexpr Permission(bool read, bool write, bool execute) : r(read), w(write), x(execute) {}
|
constexpr Permission(bool read, bool write, bool execute) : r(read), w(write), x(execute) {}
|
||||||
|
|
||||||
inline bool operator==(const Permission &rhs) const { return (this->r == rhs.r && this->w == rhs.w && this->x == rhs.x); }
|
inline bool operator==(const Permission &rhs) const { return r == rhs.r && w == rhs.w && x == rhs.x; }
|
||||||
|
|
||||||
inline bool operator!=(const Permission &rhs) const { return !operator==(rhs); }
|
inline bool operator!=(const Permission &rhs) const { return !operator==(rhs); }
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ namespace skyline {
|
|||||||
constexpr MemoryState KernelStack{0x00002013};
|
constexpr MemoryState KernelStack{0x00002013};
|
||||||
constexpr MemoryState CodeReadOnly{0x00402214};
|
constexpr MemoryState CodeReadOnly{0x00402214};
|
||||||
constexpr MemoryState CodeWritable{0x00402015};
|
constexpr MemoryState CodeWritable{0x00402015};
|
||||||
};
|
}
|
||||||
|
|
||||||
struct Region {
|
struct Region {
|
||||||
u64 address;
|
u64 address;
|
||||||
|
@ -62,7 +62,7 @@ namespace skyline {
|
|||||||
* @note 'KThread::coreMigrationMutex' **must** be locked by the calling thread prior to calling this
|
* @note 'KThread::coreMigrationMutex' **must** be locked by the calling thread prior to calling this
|
||||||
* @note This is used to handle non-cooperative core affinity mask changes where the resident core is not in its new affinity mask
|
* @note This is used to handle non-cooperative core affinity mask changes where the resident core is not in its new affinity mask
|
||||||
*/
|
*/
|
||||||
void MigrateToCore(const std::shared_ptr<type::KThread> &thread, CoreContext *¤tCore, CoreContext* targetCore, std::unique_lock<std::mutex> &lock);
|
void MigrateToCore(const std::shared_ptr<type::KThread> &thread, CoreContext *¤tCore, CoreContext *targetCore, std::unique_lock<std::mutex> &lock);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr std::chrono::milliseconds PreemptiveTimeslice{10}; //!< The duration of time a preemptive thread can run before yielding
|
static constexpr std::chrono::milliseconds PreemptiveTimeslice{10}; //!< The duration of time a preemptive thread can run before yielding
|
||||||
@ -149,11 +149,11 @@ namespace skyline {
|
|||||||
const DeviceState &state;
|
const DeviceState &state;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline SchedulerScopedLock(const DeviceState &state) : state(state) {
|
SchedulerScopedLock(const DeviceState &state) : state(state) {
|
||||||
state.scheduler->RemoveThread();
|
state.scheduler->RemoveThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ~SchedulerScopedLock() {
|
~SchedulerScopedLock() {
|
||||||
state.scheduler->InsertThread(state.thread);
|
state.scheduler->InsertThread(state.thread);
|
||||||
state.scheduler->WaitSchedule();
|
state.scheduler->WaitSchedule();
|
||||||
}
|
}
|
||||||
|
@ -87,4 +87,4 @@ namespace skyline::kernel::type {
|
|||||||
.state = memory::states::Unmapped,
|
.state = memory::states::Unmapped,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
@ -29,16 +29,10 @@ namespace skyline::kernel::type {
|
|||||||
*/
|
*/
|
||||||
void Remap(u8 *ptr, size_t size);
|
void Remap(u8 *ptr, size_t size);
|
||||||
|
|
||||||
inline span<u8> Get() override {
|
span<u8> Get() override {
|
||||||
return span(ptr, size);
|
return span(ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Updates the permissions of a block of mapped memory
|
|
||||||
* @param address The starting address to change the permissions at
|
|
||||||
* @param size The size of the partition to change the permissions of
|
|
||||||
* @param permission The new permissions to be set for the memory
|
|
||||||
*/
|
|
||||||
void UpdatePermission(u8 *ptr, size_t size, memory::Permission permission) override;
|
void UpdatePermission(u8 *ptr, size_t size, memory::Permission permission) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,10 +4,11 @@
|
|||||||
#include <nce.h>
|
#include <nce.h>
|
||||||
#include <os.h>
|
#include <os.h>
|
||||||
#include <kernel/results.h>
|
#include <kernel/results.h>
|
||||||
|
|
||||||
#include "KProcess.h"
|
#include "KProcess.h"
|
||||||
|
|
||||||
namespace skyline::kernel::type {
|
namespace skyline::kernel::type {
|
||||||
KProcess::TlsPage::TlsPage(const std::shared_ptr<KPrivateMemory> &memory) : memory(memory) {}
|
KProcess::TlsPage::TlsPage(std::shared_ptr<KPrivateMemory> memory) : memory(std::move(memory)) {}
|
||||||
|
|
||||||
u8 *KProcess::TlsPage::ReserveSlot() {
|
u8 *KProcess::TlsPage::ReserveSlot() {
|
||||||
if (index == constant::TlsSlots)
|
if (index == constant::TlsSlots)
|
||||||
|
@ -43,7 +43,7 @@ namespace skyline {
|
|||||||
u8 index{}; //!< 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
|
||||||
std::shared_ptr<KPrivateMemory> memory; //!< A single page sized memory allocation for this TLS page
|
std::shared_ptr<KPrivateMemory> memory; //!< A single page sized memory allocation for this TLS page
|
||||||
|
|
||||||
TlsPage(const std::shared_ptr<KPrivateMemory> &memory);
|
TlsPage(std::shared_ptr<KPrivateMemory> memory);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A non-null pointer to a TLS page slot on success, a nullptr will be returned if this page is full
|
* @return A non-null pointer to a TLS page slot on success, a nullptr will be returned if this page is full
|
||||||
@ -197,7 +197,7 @@ namespace skyline {
|
|||||||
/**
|
/**
|
||||||
* @brief Closes a handle in the handle table
|
* @brief Closes a handle in the handle table
|
||||||
*/
|
*/
|
||||||
inline void CloseHandle(KHandle handle) {
|
void CloseHandle(KHandle handle) {
|
||||||
handles.at(handle - constant::BaseHandleIndex) = nullptr;
|
handles.at(handle - constant::BaseHandleIndex) = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,4 +75,4 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
@ -31,7 +31,7 @@ namespace skyline::kernel::type {
|
|||||||
*/
|
*/
|
||||||
u8 *Map(u8 *ptr, u64 size, memory::Permission permission);
|
u8 *Map(u8 *ptr, u64 size, memory::Permission permission);
|
||||||
|
|
||||||
inline span<u8> Get() override {
|
span<u8> Get() override {
|
||||||
return span(guest.ptr, guest.size);
|
return span(guest.ptr, guest.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ namespace skyline::kernel::type {
|
|||||||
if (ownerPriority != currentPriority) {
|
if (ownerPriority != currentPriority) {
|
||||||
std::lock_guard waiterLock(waitingOn->waiterMutex);
|
std::lock_guard waiterLock(waitingOn->waiterMutex);
|
||||||
auto nextThread{waitingOn->waitThread};
|
auto nextThread{waitingOn->waitThread};
|
||||||
if (nextThread){
|
if (nextThread) {
|
||||||
// We need to update the location of the owner thread in the waiter queue of the thread it's waiting on
|
// We need to update the location of the owner thread in the waiter queue of the thread it's waiting on
|
||||||
std::lock_guard nextWaiterLock(nextThread->waiterMutex);
|
std::lock_guard nextWaiterLock(nextThread->waiterMutex);
|
||||||
auto &piWaiters{nextThread->waiters};
|
auto &piWaiters{nextThread->waiters};
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
|
||||||
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, const std::string &name) {
|
Loader::ExecutableLoadInfo Loader::LoadExecutable(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state, Executable &executable, size_t offset, const std::string &name) {
|
||||||
u8 *base{reinterpret_cast<u8 *>(process->memory.base.address + offset)};
|
u8 *base{reinterpret_cast<u8 *>(process->memory.base.address + offset)};
|
||||||
|
|
||||||
u64 textSize{executable.text.contents.size()};
|
u64 textSize{executable.text.contents.size()};
|
||||||
@ -109,7 +109,7 @@ namespace skyline::loader {
|
|||||||
return trace;
|
return trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Loader::GetStackTrace(const std::vector<void *> frames) {
|
std::string Loader::GetStackTrace(const std::vector<void *> &frames) {
|
||||||
std::string trace;
|
std::string trace;
|
||||||
for (const auto &frame : frames)
|
for (const auto &frame : frames)
|
||||||
trace += GetFunctionStackTrace(this, frame);
|
trace += GetFunctionStackTrace(this, frame);
|
||||||
|
@ -80,7 +80,7 @@ namespace skyline::loader {
|
|||||||
* @param name An optional name for the executable, used for symbol resolution
|
* @param name An optional name for the executable, used for symbol resolution
|
||||||
* @return An ExecutableLoadInfo struct containing the load base and size
|
* @return An ExecutableLoadInfo struct containing the load base and size
|
||||||
*/
|
*/
|
||||||
ExecutableLoadInfo LoadExecutable(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state, Executable &executable, size_t offset = 0, const std::string &name = {});
|
ExecutableLoadInfo LoadExecutable(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state, Executable &executable, size_t offset = 0, const std::string &name = {});
|
||||||
|
|
||||||
std::optional<vfs::NACP> nacp;
|
std::optional<vfs::NACP> nacp;
|
||||||
std::shared_ptr<vfs::Backing> romFs;
|
std::shared_ptr<vfs::Backing> romFs;
|
||||||
@ -94,7 +94,7 @@ namespace skyline::loader {
|
|||||||
/**
|
/**
|
||||||
* @return Entry point to the start of the main executable in the ROM
|
* @return Entry point to the start of the main executable in the ROM
|
||||||
*/
|
*/
|
||||||
virtual void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) = 0;
|
virtual void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @note The lifetime of the data contained within is tied to the lifetime of the Loader class it was obtained from (as this points to symbols from the executables loaded into memory directly)
|
* @note The lifetime of the data contained within is tied to the lifetime of the Loader class it was obtained from (as this points to symbols from the executables loaded into memory directly)
|
||||||
@ -119,6 +119,6 @@ namespace skyline::loader {
|
|||||||
/**
|
/**
|
||||||
* @return A string with the stack trace based on the stack frames in the supplied vector
|
* @return A string with the stack trace based on the stack frames in the supplied vector
|
||||||
*/
|
*/
|
||||||
std::string GetStackTrace(const std::vector<void *> frames);
|
std::string GetStackTrace(const std::vector<void *> &frames);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
#include "nca.h"
|
#include "nca.h"
|
||||||
|
|
||||||
namespace skyline::loader {
|
namespace skyline::loader {
|
||||||
NcaLoader::NcaLoader(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore) : nca(backing, keyStore) {
|
NcaLoader::NcaLoader(std::shared_ptr<vfs::Backing> backing, std::shared_ptr<crypto::KeyStore> keyStore) : nca(std::move(backing), std::move(keyStore)) {
|
||||||
if (nca.exeFs == nullptr)
|
if (nca.exeFs == nullptr)
|
||||||
throw exception("Only NCAs with an ExeFS can be loaded directly");
|
throw exception("Only NCAs with an ExeFS can be loaded directly");
|
||||||
}
|
}
|
||||||
|
|
||||||
void *NcaLoader::LoadExeFs(Loader *loader, const std::shared_ptr<vfs::FileSystem> &exeFs, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
void *NcaLoader::LoadExeFs(Loader *loader, const std::shared_ptr<vfs::FileSystem> &exeFs, const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) {
|
||||||
if (exeFs == nullptr)
|
if (exeFs == nullptr)
|
||||||
throw exception("Cannot load a null ExeFS");
|
throw exception("Cannot load a null ExeFS");
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ namespace skyline::loader {
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *NcaLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
void *NcaLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) {
|
||||||
process->npdm = vfs::NPDM(nca.exeFs->OpenFile("main.npdm"), state);
|
process->npdm = vfs::NPDM(nca.exeFs->OpenFile("main.npdm"), state);
|
||||||
return LoadExeFs(this, nca.exeFs, process, state);
|
return LoadExeFs(this, nca.exeFs, process, state);
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,14 @@ namespace skyline::loader {
|
|||||||
vfs::NCA nca; //!< The backing NCA of the loader
|
vfs::NCA nca; //!< The backing NCA of the loader
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NcaLoader(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore);
|
NcaLoader(std::shared_ptr<vfs::Backing> backing, std::shared_ptr<crypto::KeyStore> keyStore);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads an ExeFS into memory and processes it accordingly for execution
|
* @brief Loads an ExeFS into memory and processes it accordingly for execution
|
||||||
* @param exefs A filesystem object containing the ExeFS filesystem to load into memory
|
* @param exefs A filesystem object containing the ExeFS filesystem to load into memory
|
||||||
*/
|
*/
|
||||||
static void *LoadExeFs(Loader *loader, const std::shared_ptr<vfs::FileSystem> &exefs, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
static void *LoadExeFs(Loader *loader, const std::shared_ptr<vfs::FileSystem> &exefs, const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state);
|
||||||
|
|
||||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "nro.h"
|
#include "nro.h"
|
||||||
|
|
||||||
namespace skyline::loader {
|
namespace skyline::loader {
|
||||||
NroLoader::NroLoader(const std::shared_ptr<vfs::Backing> &backing) : backing(backing) {
|
NroLoader::NroLoader(std::shared_ptr<vfs::Backing> pBacking) : backing(std::move(pBacking)) {
|
||||||
header = backing->Read<NroHeader>();
|
header = backing->Read<NroHeader>();
|
||||||
|
|
||||||
if (header.magic != util::MakeMagic<u32>("NRO0"))
|
if (header.magic != util::MakeMagic<u32>("NRO0"))
|
||||||
@ -44,7 +44,7 @@ namespace skyline::loader {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *NroLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
void *NroLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) {
|
||||||
Executable executable{};
|
Executable executable{};
|
||||||
|
|
||||||
executable.text.contents = GetSegment(header.text);
|
executable.text.contents = GetSegment(header.text);
|
||||||
|
@ -68,10 +68,10 @@ namespace skyline::loader {
|
|||||||
std::vector<u8> GetSegment(const NroSegmentHeader &segment);
|
std::vector<u8> GetSegment(const NroSegmentHeader &segment);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NroLoader(const std::shared_ptr<vfs::Backing> &backing);
|
NroLoader(std::shared_ptr<vfs::Backing> backing);
|
||||||
|
|
||||||
std::vector<u8> GetIcon();
|
std::vector<u8> GetIcon() override;
|
||||||
|
|
||||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "nso.h"
|
#include "nso.h"
|
||||||
|
|
||||||
namespace skyline::loader {
|
namespace skyline::loader {
|
||||||
NsoLoader::NsoLoader(const std::shared_ptr<vfs::Backing> &backing) : backing(backing) {
|
NsoLoader::NsoLoader(std::shared_ptr<vfs::Backing> pBacking) : backing(std::move(pBacking)) {
|
||||||
u32 magic{backing->Read<u32>()};
|
u32 magic{backing->Read<u32>()};
|
||||||
|
|
||||||
if (magic != util::MakeMagic<u32>("NSO0"))
|
if (magic != util::MakeMagic<u32>("NSO0"))
|
||||||
@ -29,7 +29,7 @@ namespace skyline::loader {
|
|||||||
return outputBuffer;
|
return outputBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader::ExecutableLoadInfo NsoLoader::LoadNso(Loader *loader, const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state, size_t offset, const std::string &name) {
|
Loader::ExecutableLoadInfo NsoLoader::LoadNso(Loader *loader, const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state, size_t offset, const std::string &name) {
|
||||||
auto header{backing->Read<NsoHeader>()};
|
auto header{backing->Read<NsoHeader>()};
|
||||||
|
|
||||||
if (header.magic != util::MakeMagic<u32>("NSO0"))
|
if (header.magic != util::MakeMagic<u32>("NSO0"))
|
||||||
@ -59,7 +59,7 @@ namespace skyline::loader {
|
|||||||
return loader->LoadExecutable(process, state, executable, offset, name);
|
return loader->LoadExecutable(process, state, executable, offset, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
state.process->memory.InitializeVmm(memory::AddressSpaceType::AddressSpace39Bit);
|
state.process->memory.InitializeVmm(memory::AddressSpaceType::AddressSpace39Bit);
|
||||||
auto loadInfo{LoadNso(this, backing, process, state)};
|
auto loadInfo{LoadNso(this, backing, process, state)};
|
||||||
state.process->memory.InitializeRegions(loadInfo.base, loadInfo.size);
|
state.process->memory.InitializeRegions(loadInfo.base, loadInfo.size);
|
||||||
|
@ -78,7 +78,7 @@ namespace skyline::loader {
|
|||||||
static std::vector<u8> GetSegment(const std::shared_ptr<vfs::Backing> &backing, const NsoSegmentHeader &segment, u32 compressedSize);
|
static std::vector<u8> GetSegment(const std::shared_ptr<vfs::Backing> &backing, const NsoSegmentHeader &segment, u32 compressedSize);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NsoLoader(const std::shared_ptr<vfs::Backing> &backing);
|
NsoLoader(std::shared_ptr<vfs::Backing> backing);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads an NSO into memory, offset by the given amount
|
* @brief Loads an NSO into memory, offset by the given amount
|
||||||
@ -87,8 +87,8 @@ namespace skyline::loader {
|
|||||||
* @param name An optional name for the NSO, used for symbol resolution
|
* @param name An optional name for the NSO, used for symbol resolution
|
||||||
* @return An ExecutableLoadInfo struct containing the load base and size
|
* @return An ExecutableLoadInfo struct containing the load base and size
|
||||||
*/
|
*/
|
||||||
static ExecutableLoadInfo LoadNso(Loader *loader, const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state, size_t offset = 0, const std::string &name = {});
|
static ExecutableLoadInfo LoadNso(Loader *loader, const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state, size_t offset = 0, const std::string &name = {});
|
||||||
|
|
||||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ namespace skyline::loader {
|
|||||||
auto root{nsp->OpenDirectory("", {false, true})};
|
auto root{nsp->OpenDirectory("", {false, true})};
|
||||||
|
|
||||||
for (const auto &entry : root->Read()) {
|
for (const auto &entry : root->Read()) {
|
||||||
if (entry.name.substr(entry.name.find_last_of(".") + 1) != "nca")
|
if (entry.name.substr(entry.name.find_last_of('.') + 1) != "nca")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -35,7 +35,7 @@ namespace skyline::loader {
|
|||||||
nacp.emplace(controlRomFs->OpenFile("control.nacp"));
|
nacp.emplace(controlRomFs->OpenFile("control.nacp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *NspLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
void *NspLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) {
|
||||||
process->npdm = vfs::NPDM(programNca->exeFs->OpenFile("main.npdm"), state);
|
process->npdm = vfs::NPDM(programNca->exeFs->OpenFile("main.npdm"), state);
|
||||||
return NcaLoader::LoadExeFs(this, programNca->exeFs, process, state);
|
return NcaLoader::LoadExeFs(this, programNca->exeFs, process, state);
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@ namespace skyline::loader {
|
|||||||
public:
|
public:
|
||||||
NspLoader(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore);
|
NspLoader(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore);
|
||||||
|
|
||||||
std::vector<u8> GetIcon();
|
std::vector<u8> GetIcon() override;
|
||||||
|
|
||||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -19,13 +19,8 @@ namespace skyline::nce {
|
|||||||
struct Brk {
|
struct Brk {
|
||||||
/**
|
/**
|
||||||
* @brief Creates a BRK instruction with a specific immediate value, used for generating BRK opcodes
|
* @brief Creates a BRK instruction with a specific immediate value, used for generating BRK opcodes
|
||||||
* @param value The immediate value of the instruction
|
|
||||||
*/
|
*/
|
||||||
constexpr Brk(u16 value) {
|
constexpr Brk(u16 value) : sig0(0x0), value(value), sig1(0x6A1) {}
|
||||||
sig0 = 0x0;
|
|
||||||
this->value = value;
|
|
||||||
sig1 = 0x6A1;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool Verify() {
|
constexpr bool Verify() {
|
||||||
return (sig0 == 0x0 && sig1 == 0x6A1);
|
return (sig0 == 0x0 && sig1 == 0x6A1);
|
||||||
@ -65,15 +60,7 @@ namespace skyline::nce {
|
|||||||
* @url https://developer.arm.com/docs/ddi0596/latest/base-instructions-alphabetic-order/mrs-move-system-register
|
* @url https://developer.arm.com/docs/ddi0596/latest/base-instructions-alphabetic-order/mrs-move-system-register
|
||||||
*/
|
*/
|
||||||
struct Mrs {
|
struct Mrs {
|
||||||
/**
|
constexpr Mrs(u32 srcReg, registers::X destReg) : srcReg(srcReg), destReg(destReg), sig(0xD54) {}
|
||||||
* @param srcReg The source system register
|
|
||||||
* @param dstReg The destination Xn register
|
|
||||||
*/
|
|
||||||
constexpr Mrs(u32 srcReg, registers::X dstReg) {
|
|
||||||
this->srcReg = srcReg;
|
|
||||||
this->destReg = dstReg;
|
|
||||||
sig = 0xD53;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool Verify() {
|
constexpr bool Verify() {
|
||||||
return (sig == 0xD53);
|
return (sig == 0xD53);
|
||||||
@ -115,12 +102,9 @@ namespace skyline::nce {
|
|||||||
struct B {
|
struct B {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @param offset The relative offset to branch to (In 32-bit units)
|
* @param negate The direction of the supplied offset
|
||||||
*/
|
*/
|
||||||
constexpr B(i64 offset, bool negate = false) {
|
constexpr B(i64 offset, bool negate = false) : offset(negate ? -offset : offset), sig(0x5) {}
|
||||||
this->offset = negate ? -offset : offset;
|
|
||||||
sig = 0x5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The offset encoded within the instruction in bytes
|
* @return The offset encoded within the instruction in bytes
|
||||||
@ -148,13 +132,7 @@ namespace skyline::nce {
|
|||||||
*/
|
*/
|
||||||
struct BL {
|
struct BL {
|
||||||
public:
|
public:
|
||||||
/**
|
constexpr BL(i32 offset) : offset(offset), sig(0x25) {}
|
||||||
* @param offset The relative offset to branch to (In 32-bit units)
|
|
||||||
*/
|
|
||||||
constexpr BL(i32 offset) {
|
|
||||||
this->offset = offset;
|
|
||||||
sig = 0x25;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The offset encoded within the instruction in bytes
|
* @return The offset encoded within the instruction in bytes
|
||||||
@ -187,26 +165,14 @@ namespace skyline::nce {
|
|||||||
* @param imm16 The 16-bit value to store
|
* @param imm16 The 16-bit value to store
|
||||||
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
||||||
*/
|
*/
|
||||||
constexpr Movz(registers::X destReg, u16 imm16, u8 shift = 0) {
|
constexpr Movz(registers::X destReg, u16 imm16, u8 shift = 0) : destReg(static_cast<u8>(destReg)), imm16(imm16), hw(shift), sig(0xA5), sf(1) {}
|
||||||
this->destReg = static_cast<u8>(destReg);
|
|
||||||
this->imm16 = imm16;
|
|
||||||
hw = shift;
|
|
||||||
sig = 0xA5;
|
|
||||||
sf = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param destReg The destination Wn register to store the value in
|
* @param destReg The destination Wn register to store the value in
|
||||||
* @param imm16 The 16-bit value to store
|
* @param imm16 The 16-bit value to store
|
||||||
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
||||||
*/
|
*/
|
||||||
constexpr Movz(registers::W destReg, u16 imm16, u8 shift = 0) {
|
constexpr Movz(registers::W destReg, u16 imm16, u8 shift = 0) : destReg(static_cast<u8>(destReg)), imm16(imm16), hw(shift), sig(0xA5), sf(0) {}
|
||||||
this->destReg = static_cast<u8>(destReg);
|
|
||||||
this->imm16 = imm16;
|
|
||||||
hw = shift;
|
|
||||||
sig = 0xA5;
|
|
||||||
sf = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The shift encoded within the instruction in bytes
|
* @return The shift encoded within the instruction in bytes
|
||||||
@ -242,26 +208,14 @@ namespace skyline::nce {
|
|||||||
* @param imm16 The 16-bit value to store
|
* @param imm16 The 16-bit value to store
|
||||||
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
||||||
*/
|
*/
|
||||||
constexpr Movk(registers::X destReg, u16 imm16, u8 shift = 0) {
|
constexpr Movk(registers::X destReg, u16 imm16, u8 shift = 0) : destReg(static_cast<u8>(destReg)), imm16(imm16), hw(shift), sig(0xE5), sf(1) {}
|
||||||
this->destReg = static_cast<u8>(destReg);
|
|
||||||
this->imm16 = imm16;
|
|
||||||
hw = shift;
|
|
||||||
sig = 0xE5;
|
|
||||||
sf = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param destReg The destination Wn register to store the value in
|
* @param destReg The destination Wn register to store the value in
|
||||||
* @param imm16 The 16-bit value to store
|
* @param imm16 The 16-bit value to store
|
||||||
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
||||||
*/
|
*/
|
||||||
constexpr Movk(registers::W destReg, u16 imm16, u8 shift = 0) {
|
constexpr Movk(registers::W destReg, u16 imm16, u8 shift = 0) : destReg(static_cast<u8>(destReg)), imm16(imm16), hw(shift), sig(0xE5), sf(0) {}
|
||||||
this->destReg = static_cast<u8>(destReg);
|
|
||||||
this->imm16 = imm16;
|
|
||||||
hw = shift;
|
|
||||||
sig = 0xE5;
|
|
||||||
sf = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The shift encoded within the instruction in bytes
|
* @return The shift encoded within the instruction in bytes
|
||||||
@ -329,28 +283,14 @@ namespace skyline::nce {
|
|||||||
* @param destReg The destination Xn register to store the value in
|
* @param destReg The destination Xn register to store the value in
|
||||||
* @param srcReg The source Xn register to retrieve the value from
|
* @param srcReg The source Xn register to retrieve the value from
|
||||||
*/
|
*/
|
||||||
constexpr Mov(registers::X destReg, registers::X srcReg) {
|
constexpr Mov(registers::X destReg, registers::X srcReg) : destReg(static_cast<u8>(destReg)), sig0(0x1F), imm(0), srcReg(static_cast<u8>(srcReg)), sig1(0x150), sf(1) {}
|
||||||
this->destReg = static_cast<u8>(destReg);
|
|
||||||
sig0 = 0x1F;
|
|
||||||
imm = 0;
|
|
||||||
this->srcReg = static_cast<u8>(srcReg);
|
|
||||||
sig1 = 0x150;
|
|
||||||
sf = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a MOV instruction
|
* @brief Creates a MOV instruction
|
||||||
* @param destReg The destination Wn register to store the value in
|
* @param destReg The destination Wn register to store the value in
|
||||||
* @param srcReg The source Wn register to retrieve the value from
|
* @param srcReg The source Wn register to retrieve the value from
|
||||||
*/
|
*/
|
||||||
constexpr Mov(registers::W destReg, registers::W srcReg) {
|
constexpr Mov(registers::W destReg, registers::W srcReg) : destReg(static_cast<u8>(destReg)), sig0(0x1F), imm(0), srcReg(static_cast<u8>(srcReg)), sig1(0x150), sf(0) {}
|
||||||
this->destReg = static_cast<u8>(destReg);
|
|
||||||
sig0 = 0x1F;
|
|
||||||
imm = 0;
|
|
||||||
this->srcReg = static_cast<u8>(srcReg);
|
|
||||||
sig1 = 0x150;
|
|
||||||
sf = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool Verify() {
|
constexpr bool Verify() {
|
||||||
return (sig0 == 0x1F) && (sig1 == 0x150);
|
return (sig0 == 0x1F) && (sig1 == 0x150);
|
||||||
|
@ -12,20 +12,20 @@
|
|||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
namespace skyline::kernel {
|
namespace skyline::kernel {
|
||||||
OS::OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, const std::string &appFilesPath) : state(this, jvmManager, settings, logger), serviceManager(state), appFilesPath(appFilesPath) {}
|
OS::OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, std::string appFilesPath) : state(this, jvmManager, settings, logger), serviceManager(state), appFilesPath(std::move(appFilesPath)) {}
|
||||||
|
|
||||||
void OS::Execute(int romFd, loader::RomFormat romType) {
|
void OS::Execute(int romFd, loader::RomFormat romType) {
|
||||||
auto romFile{std::make_shared<vfs::OsBacking>(romFd)};
|
auto romFile{std::make_shared<vfs::OsBacking>(romFd)};
|
||||||
auto keyStore{std::make_shared<crypto::KeyStore>(appFilesPath)};
|
auto keyStore{std::make_shared<crypto::KeyStore>(appFilesPath)};
|
||||||
|
|
||||||
state.loader = [=]() -> std::shared_ptr<loader::Loader> {
|
state.loader = [&]() -> std::shared_ptr<loader::Loader> {
|
||||||
switch (romType) {
|
switch (romType) {
|
||||||
case loader::RomFormat::NRO:
|
case loader::RomFormat::NRO:
|
||||||
return std::make_shared<loader::NroLoader>(romFile);
|
return std::make_shared<loader::NroLoader>(std::move(romFile));
|
||||||
case loader::RomFormat::NSO:
|
case loader::RomFormat::NSO:
|
||||||
return std::make_shared<loader::NsoLoader>(romFile);
|
return std::make_shared<loader::NsoLoader>(std::move(romFile));
|
||||||
case loader::RomFormat::NCA:
|
case loader::RomFormat::NCA:
|
||||||
return std::make_shared<loader::NcaLoader>(romFile, keyStore);
|
return std::make_shared<loader::NcaLoader>(std::move(romFile), std::move(keyStore));
|
||||||
case loader::RomFormat::NSP:
|
case loader::RomFormat::NSP:
|
||||||
return std::make_shared<loader::NspLoader>(romFile, keyStore);
|
return std::make_shared<loader::NspLoader>(romFile, keyStore);
|
||||||
default:
|
default:
|
||||||
|
@ -21,7 +21,7 @@ namespace skyline::kernel {
|
|||||||
* @param settings An instance of the Settings class
|
* @param settings An instance of the Settings class
|
||||||
* @param window The ANativeWindow object to draw the screen to
|
* @param window The ANativeWindow object to draw the screen to
|
||||||
*/
|
*/
|
||||||
OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, const std::string &appFilesPath);
|
OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, std::string appFilesPath);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute a particular ROM file
|
* @brief Execute a particular ROM file
|
||||||
|
@ -28,7 +28,7 @@ namespace skyline::service::am {
|
|||||||
* @brief Writes an object to the storage
|
* @brief Writes an object to the storage
|
||||||
*/
|
*/
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
inline void Push(const ValueType &value) {
|
void Push(const ValueType &value) {
|
||||||
if (offset + sizeof(ValueType) > content.size())
|
if (offset + sizeof(ValueType) > content.size())
|
||||||
throw exception("The supplied value cannot fit into the IStorage");
|
throw exception("The supplied value cannot fit into the IStorage");
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "IStorageAccessor.h"
|
#include "IStorageAccessor.h"
|
||||||
|
|
||||||
namespace skyline::service::am {
|
namespace skyline::service::am {
|
||||||
IStorageAccessor::IStorageAccessor(const DeviceState &state, ServiceManager &manager, std::shared_ptr<IStorage> parent) : parent(parent), BaseService(state, manager) {}
|
IStorageAccessor::IStorageAccessor(const DeviceState &state, ServiceManager &manager, std::shared_ptr<IStorage> parent) : parent(std::move(parent)), BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IStorageAccessor::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IStorageAccessor::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
response.Push<i64>(parent->content.size());
|
response.Push<i64>(parent->content.size());
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
namespace skyline::service::audio {
|
namespace skyline::service::audio {
|
||||||
IAudioOut::IAudioOut(const DeviceState &state, ServiceManager &manager, u8 channelCount, u32 sampleRate) : sampleRate(sampleRate), channelCount(channelCount), releaseEvent(std::make_shared<type::KEvent>(state, false)), BaseService(state, manager) {
|
IAudioOut::IAudioOut(const DeviceState &state, ServiceManager &manager, u8 channelCount, u32 sampleRate) : sampleRate(sampleRate), channelCount(channelCount), releaseEvent(std::make_shared<type::KEvent>(state, false)), BaseService(state, manager) {
|
||||||
track = state.audio->OpenTrack(channelCount, constant::SampleRate, [this]() { this->releaseEvent->Signal(); });
|
track = state.audio->OpenTrack(channelCount, constant::SampleRate, [this]() { releaseEvent->Signal(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
IAudioOut::~IAudioOut() {
|
IAudioOut::~IAudioOut() {
|
||||||
|
@ -9,7 +9,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 {
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
namespace skyline::service::audio::IAudioRenderer {
|
namespace skyline::service::audio::IAudioRenderer {
|
||||||
IAudioRenderer::IAudioRenderer(const DeviceState &state, ServiceManager &manager, AudioRendererParameters ¶meters)
|
IAudioRenderer::IAudioRenderer(const DeviceState &state, ServiceManager &manager, AudioRendererParameters ¶meters)
|
||||||
: systemEvent(std::make_shared<type::KEvent>(state, true)), parameters(parameters), BaseService(state, manager) {
|
: systemEvent(std::make_shared<type::KEvent>(state, true)), parameters(parameters), BaseService(state, manager) {
|
||||||
track = state.audio->OpenTrack(constant::ChannelCount, constant::SampleRate, [&]() {systemEvent->Signal();});
|
track = state.audio->OpenTrack(constant::ChannelCount, constant::SampleRate, [&]() { systemEvent->Signal(); });
|
||||||
track->Start();
|
track->Start();
|
||||||
|
|
||||||
memoryPools.resize(parameters.effectCount + parameters.voiceCount * 4);
|
memoryPools.resize(parameters.effectCount + parameters.voiceCount * 4);
|
||||||
|
@ -37,7 +37,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
|||||||
public:
|
public:
|
||||||
EffectOut output{};
|
EffectOut output{};
|
||||||
|
|
||||||
inline void ProcessInput(const EffectIn &input) {
|
void ProcessInput(const EffectIn &input) {
|
||||||
if (input.isNew)
|
if (input.isNew)
|
||||||
output.state = EffectState::New;
|
output.state = EffectState::New;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ namespace skyline {
|
|||||||
constexpr u32 PerformanceMetricsDataFormatV2{5}; //!< The revision a new performance metrics format is used
|
constexpr u32 PerformanceMetricsDataFormatV2{5}; //!< The revision a new performance metrics format is used
|
||||||
constexpr u32 VaradicCommandBufferSize{5}; //!< The revision support for varying command buffer sizes was added
|
constexpr u32 VaradicCommandBufferSize{5}; //!< The revision support for varying command buffer sizes was added
|
||||||
constexpr u32 ElapsedFrameCount{5}; //!< The revision support for counting elapsed frames was added
|
constexpr u32 ElapsedFrameCount{5}; //!< The revision support for counting elapsed frames was added
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace service::audio::IAudioRenderer {
|
namespace service::audio::IAudioRenderer {
|
||||||
@ -42,7 +42,7 @@ namespace skyline {
|
|||||||
* @brief Extracts the audren revision from the magic and sets the behaviour revision to it
|
* @brief Extracts the audren revision from the magic and sets the behaviour revision to it
|
||||||
* @param revision The revision magic from guest
|
* @param revision The revision magic from guest
|
||||||
*/
|
*/
|
||||||
inline void SetUserRevision(u32 revision) {
|
void SetUserRevision(u32 revision) {
|
||||||
userRevision = ExtractVersionFromRevision(revision);
|
userRevision = ExtractVersionFromRevision(revision);
|
||||||
|
|
||||||
if (userRevision > constant::SupportedRevision)
|
if (userRevision > constant::SupportedRevision)
|
||||||
@ -52,35 +52,35 @@ namespace skyline {
|
|||||||
/**
|
/**
|
||||||
* @return Whether the splitter is supported
|
* @return Whether the splitter is supported
|
||||||
*/
|
*/
|
||||||
inline bool SplitterSupported() {
|
bool SplitterSupported() {
|
||||||
return userRevision >= constant::supportTags::Splitter;
|
return userRevision >= constant::supportTags::Splitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether the splitter is fixed
|
* @return Whether the splitter is fixed
|
||||||
*/
|
*/
|
||||||
inline bool SplitterBugFixed() {
|
bool SplitterBugFixed() {
|
||||||
return userRevision >= constant::supportTags::SplitterBugFix;
|
return userRevision >= constant::supportTags::SplitterBugFix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether the new performance metrics format is used
|
* @return Whether the new performance metrics format is used
|
||||||
*/
|
*/
|
||||||
inline bool UsesPerformanceMetricDataFormatV2() {
|
bool UsesPerformanceMetricDataFormatV2() {
|
||||||
return userRevision >= constant::supportTags::PerformanceMetricsDataFormatV2;
|
return userRevision >= constant::supportTags::PerformanceMetricsDataFormatV2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether varying command buffer sizes are supported
|
* @return Whether varying command buffer sizes are supported
|
||||||
*/
|
*/
|
||||||
inline bool VaradicCommandBufferSizeSupported() {
|
bool VaradicCommandBufferSizeSupported() {
|
||||||
return userRevision >= constant::supportTags::VaradicCommandBufferSize;
|
return userRevision >= constant::supportTags::VaradicCommandBufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether elapsed frame counting is supported
|
* @return Whether elapsed frame counting is supported
|
||||||
*/
|
*/
|
||||||
inline bool ElapsedFrameCountSupported() {
|
bool ElapsedFrameCountSupported() {
|
||||||
return userRevision >= constant::supportTags::ElapsedFrameCount;
|
return userRevision >= constant::supportTags::ElapsedFrameCount;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -45,7 +45,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
|||||||
std::vector<std::array<i16, 2>> adpcmCoefficients(input.adpcmCoeffsSize / (sizeof(u16) * 2));
|
std::vector<std::array<i16, 2>> adpcmCoefficients(input.adpcmCoeffsSize / (sizeof(u16) * 2));
|
||||||
span(adpcmCoefficients).copy_from(span(input.adpcmCoeffs, input.adpcmCoeffsSize / sizeof(u32)));
|
span(adpcmCoefficients).copy_from(span(input.adpcmCoeffs, input.adpcmCoeffsSize / sizeof(u32)));
|
||||||
|
|
||||||
adpcmDecoder = skyline::audio::AdpcmDecoder(adpcmCoefficients);
|
adpcmDecoder = skyline::audio::AdpcmDecoder(std::move(adpcmCoefficients));
|
||||||
}
|
}
|
||||||
|
|
||||||
SetWaveBufferIndex(static_cast<u8>(input.baseWaveBufferIndex));
|
SetWaveBufferIndex(static_cast<u8>(input.baseWaveBufferIndex));
|
||||||
|
@ -122,7 +122,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
|||||||
/**
|
/**
|
||||||
* @return If the voice is currently playable
|
* @return If the voice is currently playable
|
||||||
*/
|
*/
|
||||||
inline bool Playable() {
|
bool Playable() {
|
||||||
return acquired && playbackState == skyline::audio::AudioOutState::Started && waveBuffers[bufferIndex].size != 0;
|
return acquired && playbackState == skyline::audio::AudioOutState::Started && waveBuffers[bufferIndex].size != 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#define SERVICE_DECL_AUTO(name, value) decltype(value) name = value
|
#define SERVICE_DECL_AUTO(name, value) decltype(value) name = value
|
||||||
#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) override { \
|
||||||
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); \
|
||||||
}
|
}
|
||||||
@ -63,6 +63,6 @@ namespace skyline::service {
|
|||||||
/**
|
/**
|
||||||
* @brief Handles an IPC Request to a service
|
* @brief Handles an IPC Request to a service
|
||||||
*/
|
*/
|
||||||
Result HandleRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);;
|
Result HandleRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ namespace skyline::service::nvdrv {
|
|||||||
/**
|
/**
|
||||||
* @brief Synchronizes the fence's value with its underlying syncpoint
|
* @brief Synchronizes the fence's value with its underlying syncpoint
|
||||||
*/
|
*/
|
||||||
inline void UpdateValue(NvHostSyncpoint &hostSyncpoint) {
|
void UpdateValue(NvHostSyncpoint &hostSyncpoint) {
|
||||||
value = hostSyncpoint.UpdateMin(id);
|
value = hostSyncpoint.UpdateMin(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -43,7 +43,7 @@ namespace skyline::service {
|
|||||||
* @return A reference to an item from the top of data
|
* @return A reference to an item from the top of data
|
||||||
*/
|
*/
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
inline ValueType &Pop() {
|
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;
|
||||||
|
@ -21,7 +21,7 @@ namespace skyline::service::fssrv {
|
|||||||
u64 size;
|
u64 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
IDirectory::IDirectory(std::shared_ptr<vfs::Directory> backing, std::shared_ptr<vfs::FileSystem> backingFs, const DeviceState &state, ServiceManager &manager) : backing(backing), backingFs(backingFs), BaseService(state, manager) {}
|
IDirectory::IDirectory(std::shared_ptr<vfs::Directory> backing, std::shared_ptr<vfs::FileSystem> backingFs, const DeviceState &state, ServiceManager &manager) : backing(std::move(backing)), backingFs(std::move(backingFs)), BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IDirectory::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IDirectory::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto entries{backing->Read()};
|
auto entries{backing->Read()};
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "IFile.h"
|
#include "IFile.h"
|
||||||
|
|
||||||
namespace skyline::service::fssrv {
|
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(std::move(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>()};
|
||||||
|
@ -16,7 +16,7 @@ namespace skyline::service::fssrv {
|
|||||||
std::shared_ptr<vfs::Backing> backing;
|
std::shared_ptr<vfs::Backing> backing;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IFile(std::shared_ptr<vfs::Backing> &backing, const DeviceState &state, ServiceManager &manager);
|
IFile(std::shared_ptr<vfs::Backing> backing, const DeviceState &state, ServiceManager &manager);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads a buffer from a region of an IFile
|
* @brief Reads a buffer from a region of an IFile
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "IFileSystem.h"
|
#include "IFileSystem.h"
|
||||||
|
|
||||||
namespace skyline::service::fssrv {
|
namespace skyline::service::fssrv {
|
||||||
IFileSystem::IFileSystem(std::shared_ptr<vfs::FileSystem> backing, const DeviceState &state, ServiceManager &manager) : backing(backing), BaseService(state, manager) {}
|
IFileSystem::IFileSystem(std::shared_ptr<vfs::FileSystem> backing, const DeviceState &state, ServiceManager &manager) : backing(std::move(backing)), BaseService(state, manager) {}
|
||||||
|
|
||||||
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_string(true));
|
std::string path(request.inputBuf.at(0).as_string(true));
|
||||||
@ -42,7 +42,7 @@ namespace skyline::service::fssrv {
|
|||||||
if (file == nullptr)
|
if (file == nullptr)
|
||||||
return result::UnexpectedFailure;
|
return result::UnexpectedFailure;
|
||||||
else
|
else
|
||||||
manager.RegisterService(std::make_shared<IFile>(file, state, manager), session, response);
|
manager.RegisterService(std::make_shared<IFile>(std::move(file), state, manager), session, response);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ namespace skyline::service::fssrv {
|
|||||||
auto listMode{request.Pop<vfs::Directory::ListMode>()};
|
auto listMode{request.Pop<vfs::Directory::ListMode>()};
|
||||||
auto directory{backing->OpenDirectory(path, listMode)};
|
auto directory{backing->OpenDirectory(path, listMode)};
|
||||||
|
|
||||||
manager.RegisterService(std::make_shared<IDirectory>(directory, backing, state, manager), session, response);
|
manager.RegisterService(std::make_shared<IDirectory>(std::move(directory), backing, state, manager), session, response);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ namespace skyline::service::fssrv {
|
|||||||
IFileSystemProxy::IFileSystemProxy(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
IFileSystemProxy::IFileSystemProxy(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IFileSystemProxy::SetCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IFileSystemProxy::SetCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
process = request.Pop<pid_t>();
|
process = request.Pop<u64>();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ namespace skyline::service::fssrv {
|
|||||||
return "/nand/temp";
|
return "/nand/temp";
|
||||||
default:
|
default:
|
||||||
throw exception("Unsupported savedata ID: {}", spaceId);
|
throw exception("Unsupported savedata ID: {}", spaceId);
|
||||||
};
|
}
|
||||||
}()};
|
}()};
|
||||||
|
|
||||||
switch (attribute.type) {
|
switch (attribute.type) {
|
||||||
@ -54,7 +54,7 @@ namespace skyline::service::fssrv {
|
|||||||
return fmt::format("{}/save/cache/{:016X}/", spaceIdStr, attribute.programId);
|
return fmt::format("{}/save/cache/{:016X}/", spaceIdStr, attribute.programId);
|
||||||
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);
|
||||||
|
@ -48,7 +48,7 @@ namespace skyline::service::fssrv {
|
|||||||
*/
|
*/
|
||||||
class IFileSystemProxy : public BaseService {
|
class IFileSystemProxy : public BaseService {
|
||||||
public:
|
public:
|
||||||
pid_t process{}; //!< The PID as set by SetCurrentProcess
|
u64 process{}; //!< The PID as set by SetCurrentProcess
|
||||||
|
|
||||||
IFileSystemProxy(const DeviceState &state, ServiceManager &manager);
|
IFileSystemProxy(const DeviceState &state, ServiceManager &manager);
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "IStorage.h"
|
#include "IStorage.h"
|
||||||
|
|
||||||
namespace skyline::service::fssrv {
|
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(std::move(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>()};
|
||||||
|
@ -16,7 +16,7 @@ namespace skyline::service::fssrv {
|
|||||||
std::shared_ptr<vfs::Backing> backing;
|
std::shared_ptr<vfs::Backing> backing;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IStorage(std::shared_ptr<vfs::Backing> &backing, const DeviceState &state, ServiceManager &manager);
|
IStorage(std::shared_ptr<vfs::Backing> backing, const DeviceState &state, ServiceManager &manager);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads a buffer from a region of an IStorage
|
* @brief Reads a buffer from a region of an IStorage
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "GraphicBufferProducer.h"
|
#include "GraphicBufferProducer.h"
|
||||||
|
|
||||||
namespace skyline::service::hosbinder {
|
namespace skyline::service::hosbinder {
|
||||||
Buffer::Buffer(const GbpBuffer &gbpBuffer, const std::shared_ptr<gpu::Texture> &texture) : gbpBuffer(gbpBuffer), texture(texture) {}
|
Buffer::Buffer(const GbpBuffer &gbpBuffer, std::shared_ptr<gpu::Texture> texture) : gbpBuffer(gbpBuffer), texture(std::move(texture)) {}
|
||||||
|
|
||||||
GraphicBufferProducer::GraphicBufferProducer(const DeviceState &state) : state(state) {}
|
GraphicBufferProducer::GraphicBufferProducer(const DeviceState &state) : state(state) {}
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ namespace skyline::service::hosbinder {
|
|||||||
std::optional<u32> slot{std::nullopt};
|
std::optional<u32> slot{std::nullopt};
|
||||||
while (!slot) {
|
while (!slot) {
|
||||||
for (auto &buffer : queue) {
|
for (auto &buffer : queue) {
|
||||||
if (buffer.second->status == BufferStatus::Free && (format ? buffer.second->gbpBuffer.format == format : true) && buffer.second->gbpBuffer.width == width && buffer.second->gbpBuffer.height == height && (buffer.second->gbpBuffer.usage & usage) == usage) {
|
if (buffer.second->status == BufferStatus::Free && (format == 0 || buffer.second->gbpBuffer.format == format) && buffer.second->gbpBuffer.width == width && buffer.second->gbpBuffer.height == height && (buffer.second->gbpBuffer.usage & usage) == usage) {
|
||||||
slot = buffer.first;
|
slot = buffer.first;
|
||||||
buffer.second->status = BufferStatus::Dequeued;
|
buffer.second->status = BufferStatus::Dequeued;
|
||||||
break;
|
break;
|
||||||
|
@ -50,7 +50,7 @@ namespace skyline::service::hosbinder {
|
|||||||
std::shared_ptr<gpu::Texture> texture;
|
std::shared_ptr<gpu::Texture> texture;
|
||||||
GbpBuffer gbpBuffer;
|
GbpBuffer gbpBuffer;
|
||||||
|
|
||||||
Buffer(const GbpBuffer &gbpBuffer, const std::shared_ptr<gpu::Texture> &texture);
|
Buffer(const GbpBuffer &gbpBuffer, std::shared_ptr<gpu::Texture> texture);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -140,7 +140,6 @@ namespace skyline::service::nvdrv {
|
|||||||
else
|
else
|
||||||
buffer = request.outputBuf[0];
|
buffer = request.outputBuf[0];
|
||||||
|
|
||||||
|
|
||||||
response.Push(device->HandleIoctl(cmd, device::IoctlType::Ioctl3, buffer, request.outputBuf.size() >= 2 ? request.outputBuf[1] : span<u8>()));
|
response.Push(device->HandleIoctl(cmd, device::IoctlType::Ioctl3, buffer, request.outputBuf.size() >= 2 ? request.outputBuf[1] : span<u8>()));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#define NVDEVICE_DECL_AUTO(name, value) decltype(value) name = value
|
#define NVDEVICE_DECL_AUTO(name, value) decltype(value) name = value
|
||||||
#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) override { \
|
||||||
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); \
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
const DeviceState &state;
|
const DeviceState &state;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline NvDevice(const DeviceState &state) : state(state) {}
|
NvDevice(const DeviceState &state) : state(state) {}
|
||||||
|
|
||||||
virtual ~NvDevice() = default;
|
virtual ~NvDevice() = default;
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
*/
|
*/
|
||||||
NvStatus HandleIoctl(u32 cmd, IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
NvStatus HandleIoctl(u32 cmd, IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
||||||
|
|
||||||
inline virtual std::shared_ptr<kernel::type::KEvent> QueryEvent(u32 eventId) {
|
virtual std::shared_ptr<kernel::type::KEvent> QueryEvent(u32 eventId) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -88,7 +88,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
*/
|
*/
|
||||||
NvStatus SetUserData(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
NvStatus SetUserData(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
||||||
|
|
||||||
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId);
|
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId) override;
|
||||||
|
|
||||||
NVDEVICE_DECL(
|
NVDEVICE_DECL(
|
||||||
NVFUNC(0x4801, NvHostChannel, SetNvmapFd),
|
NVFUNC(0x4801, NvHostChannel, SetNvmapFd),
|
||||||
|
@ -54,15 +54,14 @@ namespace skyline::service::nvdrv::device {
|
|||||||
event->ResetSignal();
|
event->ResetSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncpointEvent::Wait(const std::shared_ptr<gpu::GPU> &gpuState, const Fence &fence) {
|
void SyncpointEvent::Wait(const std::shared_ptr<gpu::GPU> &gpuState, const Fence &pFence) {
|
||||||
std::lock_guard lock(mutex);
|
std::lock_guard lock(mutex);
|
||||||
|
|
||||||
this->fence = fence;
|
fence = pFence;
|
||||||
state = State::Waiting;
|
state = State::Waiting;
|
||||||
waiterId = gpuState->syncpoints.at(fence.id).RegisterWaiter(fence.value, [this] { Signal(); });
|
waiterId = gpuState->syncpoints.at(fence.id).RegisterWaiter(fence.value, [this] { Signal(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NvHostCtrl::NvHostCtrl(const DeviceState &state) : NvDevice(state) {}
|
NvHostCtrl::NvHostCtrl(const DeviceState &state) : NvDevice(state) {}
|
||||||
|
|
||||||
u32 NvHostCtrl::FindFreeSyncpointEvent(u32 syncpointId) {
|
u32 NvHostCtrl::FindFreeSyncpointEvent(u32 syncpointId) {
|
||||||
|
@ -99,7 +99,7 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
NvStatus SyncpointRegisterEvent(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
NvStatus SyncpointRegisterEvent(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
||||||
|
|
||||||
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId);
|
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId) override;
|
||||||
|
|
||||||
NVDEVICE_DECL(
|
NVDEVICE_DECL(
|
||||||
NVFUNC(0x001B, NvHostCtrl, GetConfig),
|
NVFUNC(0x001B, NvHostCtrl, GetConfig),
|
||||||
|
@ -48,7 +48,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
*/
|
*/
|
||||||
NvStatus GetActiveSlotMask(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
NvStatus GetActiveSlotMask(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
||||||
|
|
||||||
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId);
|
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId) override;
|
||||||
|
|
||||||
NVDEVICE_DECL(
|
NVDEVICE_DECL(
|
||||||
NVFUNC(0x4701, NvHostCtrlGpu, ZCullGetCtxSize),
|
NVFUNC(0x4701, NvHostCtrlGpu, ZCullGetCtxSize),
|
||||||
|
@ -39,7 +39,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
|
|
||||||
NvMap(const DeviceState &state);
|
NvMap(const DeviceState &state);
|
||||||
|
|
||||||
inline std::shared_ptr<NvMapObject> GetObject(u32 handle) {
|
std::shared_ptr<NvMapObject> GetObject(u32 handle) {
|
||||||
if (handle-- == 0)
|
if (handle-- == 0)
|
||||||
throw std::out_of_range("0 is an invalid nvmap handle");
|
throw std::out_of_range("0 is an invalid nvmap handle");
|
||||||
std::shared_lock lock(mapMutex);
|
std::shared_lock lock(mapMutex);
|
||||||
|
@ -62,7 +62,7 @@ namespace skyline::service::nvdrv {
|
|||||||
* @return A shared pointer to the device
|
* @return A shared pointer to the device
|
||||||
*/
|
*/
|
||||||
template<typename objectClass>
|
template<typename objectClass>
|
||||||
inline std::shared_ptr<objectClass> GetDevice(u32 fd) {
|
std::shared_ptr<objectClass> GetDevice(u32 fd) {
|
||||||
return std::static_pointer_cast<objectClass>(GetDevice(fd));
|
return std::static_pointer_cast<objectClass>(GetDevice(fd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ namespace skyline::service {
|
|||||||
void RegisterService(std::shared_ptr<BaseService> serviceObject, type::KSession &session, ipc::IpcResponse &response);
|
void RegisterService(std::shared_ptr<BaseService> serviceObject, type::KSession &session, ipc::IpcResponse &response);
|
||||||
|
|
||||||
template<typename ServiceType>
|
template<typename ServiceType>
|
||||||
inline void RegisterService(std::shared_ptr<ServiceType> serviceObject, type::KSession &session, ipc::IpcResponse &response) {
|
void RegisterService(std::shared_ptr<ServiceType> serviceObject, type::KSession &session, ipc::IpcResponse &response) {
|
||||||
RegisterService(std::static_pointer_cast<BaseService>(serviceObject), session, response);
|
RegisterService(std::static_pointer_cast<BaseService>(serviceObject), session, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ namespace skyline::service::timesrv {
|
|||||||
ITimeZoneService::ITimeZoneService(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
ITimeZoneService::ITimeZoneService(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
||||||
|
|
||||||
Result ITimeZoneService::ToCalendarTimeWithMyRule(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result ITimeZoneService::ToCalendarTimeWithMyRule(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto& time{request.Pop<u64>()};
|
auto &time{request.Pop<u64>()};
|
||||||
auto calender{*std::gmtime(reinterpret_cast<const time_t *>(&time))};
|
auto calender{*std::gmtime(reinterpret_cast<const time_t *>(&time))};
|
||||||
|
|
||||||
CalendarTime calendarTime{
|
CalendarTime calendarTime{
|
||||||
|
@ -48,7 +48,7 @@ namespace skyline::vfs {
|
|||||||
* @brief Implicit casting for reading into spans of different types
|
* @brief Implicit casting for reading into spans of different types
|
||||||
*/
|
*/
|
||||||
template<typename T, typename std::enable_if<!std::is_same_v<T, u8>, bool>::type = true>
|
template<typename T, typename std::enable_if<!std::is_same_v<T, u8>, bool>::type = true>
|
||||||
inline size_t Read(span <T> output, size_t offset = 0) {
|
size_t Read(span <T> output, size_t offset = 0) {
|
||||||
return Read(output.template cast<u8>(), offset);
|
return Read(output.template cast<u8>(), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ namespace skyline::vfs {
|
|||||||
* @return The object that was read
|
* @return The object that was read
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T Read(size_t offset = 0) {
|
T Read(size_t offset = 0) {
|
||||||
T object;
|
T object;
|
||||||
Read(span(reinterpret_cast<u8 *>(&object), sizeof(T)), offset);
|
Read(span(reinterpret_cast<u8 *>(&object), sizeof(T)), offset);
|
||||||
return object;
|
return object;
|
||||||
@ -80,7 +80,7 @@ namespace skyline::vfs {
|
|||||||
* @param offset The offset where the input should be written
|
* @param offset The offset where the input should be written
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void WriteObject(const T &object, size_t offset = 0) {
|
void WriteObject(const T &object, size_t offset = 0) {
|
||||||
size_t size;
|
size_t size;
|
||||||
if ((size = Write(span(reinterpret_cast<u8 *>(&object), sizeof(T)), offset)) != sizeof(T))
|
if ((size = Write(span(reinterpret_cast<u8 *>(&object), sizeof(T)), offset)) != sizeof(T))
|
||||||
throw exception("Object wasn't written fully into output backing: {}/{}", size, sizeof(T));
|
throw exception("Object wasn't written fully into output backing: {}/{}", size, sizeof(T));
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
namespace skyline::vfs {
|
namespace skyline::vfs {
|
||||||
constexpr size_t SectorSize{0x10};
|
constexpr size_t SectorSize{0x10};
|
||||||
|
|
||||||
CtrEncryptedBacking::CtrEncryptedBacking(crypto::KeyStore::Key128 &ctr, crypto::KeyStore::Key128 &key, const std::shared_ptr<Backing> &backing, size_t baseOffset) : Backing({true, false, false}), ctr(ctr), cipher(key, MBEDTLS_CIPHER_AES_128_CTR), backing(backing), baseOffset(baseOffset) {}
|
CtrEncryptedBacking::CtrEncryptedBacking(crypto::KeyStore::Key128 ctr, crypto::KeyStore::Key128 key, std::shared_ptr<Backing> backing, size_t baseOffset) : Backing({true, false, false}), ctr(ctr), cipher(key, MBEDTLS_CIPHER_AES_128_CTR), backing(std::move(backing)), baseOffset(baseOffset) {}
|
||||||
|
|
||||||
void CtrEncryptedBacking::UpdateCtr(u64 offset) {
|
void CtrEncryptedBacking::UpdateCtr(u64 offset) {
|
||||||
offset >>= 4;
|
offset >>= 4;
|
||||||
|
@ -25,7 +25,7 @@ namespace skyline::vfs {
|
|||||||
void UpdateCtr(u64 offset);
|
void UpdateCtr(u64 offset);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CtrEncryptedBacking(crypto::KeyStore::Key128 &ctr, crypto::KeyStore::Key128 &key, const std::shared_ptr<Backing> &backing, size_t baseOffset);
|
CtrEncryptedBacking(crypto::KeyStore::Key128 ctr, crypto::KeyStore::Key128 key, std::shared_ptr<Backing> backing, size_t baseOffset);
|
||||||
|
|
||||||
size_t Read(span<u8> output, size_t offset = 0) override;
|
size_t Read(span<u8> output, size_t offset = 0) override;
|
||||||
};
|
};
|
||||||
|
@ -61,7 +61,7 @@ namespace skyline::vfs {
|
|||||||
* @param path The path to the file
|
* @param path The path to the file
|
||||||
* @return Whether the file exists
|
* @return Whether the file exists
|
||||||
*/
|
*/
|
||||||
inline bool FileExists(const std::string &path) {
|
bool FileExists(const std::string &path) {
|
||||||
auto entry{GetEntryType(path)};
|
auto entry{GetEntryType(path)};
|
||||||
return entry && *entry == Directory::EntryType::File;
|
return entry && *entry == Directory::EntryType::File;
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ namespace skyline::vfs {
|
|||||||
* @param path The path to the directory
|
* @param path The path to the directory
|
||||||
* @return Whether the directory exists
|
* @return Whether the directory exists
|
||||||
*/
|
*/
|
||||||
inline bool DirectoryExists(const std::string &path) {
|
bool DirectoryExists(const std::string &path) {
|
||||||
auto entry{GetEntryType(path)};
|
auto entry{GetEntryType(path)};
|
||||||
return entry && *entry == Directory::EntryType::Directory;
|
return entry && *entry == Directory::EntryType::Directory;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <crypto/aes_cipher.h>
|
#include <crypto/aes_cipher.h>
|
||||||
#include <loader/loader.h>
|
#include <loader/loader.h>
|
||||||
|
|
||||||
#include "ctr_encrypted_backing.h"
|
#include "ctr_encrypted_backing.h"
|
||||||
#include "region_backing.h"
|
#include "region_backing.h"
|
||||||
#include "partition_filesystem.h"
|
#include "partition_filesystem.h"
|
||||||
@ -13,7 +14,7 @@
|
|||||||
namespace skyline::vfs {
|
namespace skyline::vfs {
|
||||||
using namespace loader;
|
using namespace loader;
|
||||||
|
|
||||||
NCA::NCA(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore) : backing(backing), keyStore(keyStore) {
|
NCA::NCA(std::shared_ptr<vfs::Backing> pBacking, std::shared_ptr<crypto::KeyStore> pKeyStore) : backing(std::move(pBacking)), keyStore(std::move(pKeyStore)) {
|
||||||
header = backing->Read<NcaHeader>();
|
header = backing->Read<NcaHeader>();
|
||||||
|
|
||||||
if (header.magic != util::MakeMagic<u32>("NCA3")) {
|
if (header.magic != util::MakeMagic<u32>("NCA3")) {
|
||||||
@ -116,7 +117,7 @@ namespace skyline::vfs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
crypto::KeyStore::Key128 NCA::GetKeyAreaKey(NCA::NcaSectionEncryptionType type) {
|
crypto::KeyStore::Key128 NCA::GetKeyAreaKey(NCA::NcaSectionEncryptionType type) {
|
||||||
auto keyArea{[&](crypto::KeyStore::IndexedKeys128 &keys) {
|
auto keyArea{[this, &type](crypto::KeyStore::IndexedKeys128 &keys) {
|
||||||
u8 keyGeneration{GetKeyGeneration()};
|
u8 keyGeneration{GetKeyGeneration()};
|
||||||
|
|
||||||
auto &keyArea{keys[keyGeneration]};
|
auto &keyArea{keys[keyGeneration]};
|
||||||
|
@ -193,7 +193,7 @@ namespace skyline {
|
|||||||
std::shared_ptr<Backing> romFs; //!< The backing for this NCA's RomFS section
|
std::shared_ptr<Backing> romFs; //!< The backing for this NCA's RomFS section
|
||||||
NcaContentType contentType; //!< The content type of the NCA
|
NcaContentType contentType; //!< The content type of the NCA
|
||||||
|
|
||||||
NCA(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore);
|
NCA(std::shared_ptr<vfs::Backing> backing, std::shared_ptr<crypto::KeyStore> keyStore);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ namespace skyline {
|
|||||||
u32 size;
|
u32 size;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T Read(const std::shared_ptr<vfs::Backing> &backing, size_t baseOffset = 0) {
|
T Read(const std::shared_ptr<vfs::Backing> &backing, size_t baseOffset = 0) {
|
||||||
if (sizeof(T) > size)
|
if (sizeof(T) > size)
|
||||||
throw exception("Section size ({}) smaller than Read type size ({})", size, sizeof(T));
|
throw exception("Section size ({}) smaller than Read type size ({})", size, sizeof(T));
|
||||||
return backing->Read<T>(baseOffset + offset);
|
return backing->Read<T>(baseOffset + offset);
|
||||||
|
@ -42,11 +42,11 @@ namespace skyline::vfs {
|
|||||||
return static_cast<size_t>(ret);
|
return static_cast<size_t>(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OsBacking::Resize(size_t size) {
|
void OsBacking::Resize(size_t pSize) {
|
||||||
int ret{ftruncate(fd, size)};
|
int ret{ftruncate(fd, pSize)};
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
throw exception("Failed to resize file: {}", strerror(errno));
|
throw exception("Failed to resize file: {}", strerror(errno));
|
||||||
|
|
||||||
this->size = size;
|
size = pSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ namespace skyline::vfs {
|
|||||||
return std::make_shared<OsFileSystemDirectory>(basePath + path, listMode);
|
return std::make_shared<OsFileSystemDirectory>(basePath + path, listMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
OsFileSystemDirectory::OsFileSystemDirectory(const std::string &path, Directory::ListMode listMode) : Directory(listMode), path(path) {}
|
OsFileSystemDirectory::OsFileSystemDirectory(std::string path, Directory::ListMode listMode) : Directory(listMode), path(std::move(path)) {}
|
||||||
|
|
||||||
std::vector<Directory::Entry> OsFileSystemDirectory::Read() {
|
std::vector<Directory::Entry> OsFileSystemDirectory::Read() {
|
||||||
if (!listMode.file && !listMode.directory)
|
if (!listMode.file && !listMode.directory)
|
||||||
|
@ -35,7 +35,7 @@ namespace skyline::vfs {
|
|||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OsFileSystemDirectory(const std::string &path, ListMode listMode);
|
OsFileSystemDirectory(std::string path, ListMode listMode);
|
||||||
|
|
||||||
std::vector<Entry> Read();
|
std::vector<Entry> Read();
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "partition_filesystem.h"
|
#include "partition_filesystem.h"
|
||||||
|
|
||||||
namespace skyline::vfs {
|
namespace skyline::vfs {
|
||||||
PartitionFileSystem::PartitionFileSystem(std::shared_ptr<Backing> backing) : FileSystem(), backing(backing) {
|
PartitionFileSystem::PartitionFileSystem(const std::shared_ptr<Backing> &backing) : FileSystem(), backing(backing) {
|
||||||
header = backing->Read<FsHeader>();
|
header = backing->Read<FsHeader>();
|
||||||
|
|
||||||
if (header.magic == util::MakeMagic<u32>("PFS0"))
|
if (header.magic == util::MakeMagic<u32>("PFS0"))
|
||||||
@ -27,7 +27,7 @@ namespace skyline::vfs {
|
|||||||
auto entry{backing->Read<PartitionFileEntry>(entryOffset)};
|
auto entry{backing->Read<PartitionFileEntry>(entryOffset)};
|
||||||
|
|
||||||
std::string name(&stringTable[entry.stringTableOffset]);
|
std::string name(&stringTable[entry.stringTableOffset]);
|
||||||
fileMap.emplace(name, std::move(entry));
|
fileMap.emplace(name, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ namespace skyline::vfs {
|
|||||||
return std::make_shared<PartitionFileSystemDirectory>(fileList, listMode);
|
return std::make_shared<PartitionFileSystemDirectory>(fileList, listMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionFileSystemDirectory::PartitionFileSystemDirectory(const std::vector<Entry> &fileList, ListMode listMode) : Directory(listMode), fileList(fileList) {}
|
PartitionFileSystemDirectory::PartitionFileSystemDirectory(std::vector<Entry> fileList, ListMode listMode) : Directory(listMode), fileList(std::move(fileList)) {}
|
||||||
|
|
||||||
std::vector<Directory::Entry> PartitionFileSystemDirectory::Read() {
|
std::vector<Directory::Entry> PartitionFileSystemDirectory::Read() {
|
||||||
if (listMode.file)
|
if (listMode.file)
|
||||||
|
@ -40,7 +40,7 @@ namespace skyline::vfs {
|
|||||||
std::unordered_map<std::string, PartitionFileEntry> fileMap; //!< A map that maps file names to their corresponding entry
|
std::unordered_map<std::string, PartitionFileEntry> fileMap; //!< A map that maps file names to their corresponding entry
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PartitionFileSystem(std::shared_ptr<Backing> backing);
|
PartitionFileSystem(const std::shared_ptr<Backing> &backing);
|
||||||
|
|
||||||
std::shared_ptr<Backing> OpenFile(const std::string &path, Backing::Mode mode = {true, false, false});
|
std::shared_ptr<Backing> OpenFile(const std::string &path, Backing::Mode mode = {true, false, false});
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ namespace skyline::vfs {
|
|||||||
std::vector<Entry> fileList; //!< A list of every file in the PFS root directory
|
std::vector<Entry> fileList; //!< A list of every file in the PFS root directory
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PartitionFileSystemDirectory(const std::vector<Entry> &fileList, ListMode listMode);
|
PartitionFileSystemDirectory(std::vector<Entry> fileList, ListMode listMode);
|
||||||
|
|
||||||
std::vector<Entry> Read();
|
std::vector<Entry> Read();
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "rom_filesystem.h"
|
#include "rom_filesystem.h"
|
||||||
|
|
||||||
namespace skyline::vfs {
|
namespace skyline::vfs {
|
||||||
RomFileSystem::RomFileSystem(std::shared_ptr<Backing> backing) : FileSystem(), backing(backing) {
|
RomFileSystem::RomFileSystem(std::shared_ptr<Backing> pBacking) : FileSystem(), backing(std::move(pBacking)) {
|
||||||
header = backing->Read<RomFsHeader>();
|
header = backing->Read<RomFsHeader>();
|
||||||
TraverseDirectory(0, "");
|
TraverseDirectory(0, "");
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ namespace skyline::vfs {
|
|||||||
void RomFileSystem::TraverseDirectory(u32 offset, const std::string &path) {
|
void RomFileSystem::TraverseDirectory(u32 offset, const std::string &path) {
|
||||||
auto entry{backing->Read<RomFsDirectoryEntry>(header.dirMetaTableOffset + offset)};
|
auto entry{backing->Read<RomFsDirectoryEntry>(header.dirMetaTableOffset + offset)};
|
||||||
|
|
||||||
std::string childPath{path};
|
std::string childPath(path);
|
||||||
if (entry.nameSize) {
|
if (entry.nameSize) {
|
||||||
std::vector<char> name(entry.nameSize);
|
std::vector<char> name(entry.nameSize);
|
||||||
backing->Read(span(name), header.dirMetaTableOffset + offset + sizeof(RomFsDirectoryEntry));
|
backing->Read(span(name), header.dirMetaTableOffset + offset + sizeof(RomFsDirectoryEntry));
|
||||||
@ -76,7 +76,7 @@ namespace skyline::vfs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RomFileSystemDirectory::RomFileSystemDirectory(const std::shared_ptr<Backing> &backing, const RomFileSystem::RomFsHeader &header, const RomFileSystem::RomFsDirectoryEntry &ownEntry, ListMode listMode) : Directory(listMode), backing(backing), header(header), ownEntry(ownEntry) {}
|
RomFileSystemDirectory::RomFileSystemDirectory(std::shared_ptr<Backing> backing, const RomFileSystem::RomFsHeader &header, const RomFileSystem::RomFsDirectoryEntry &ownEntry, ListMode listMode) : Directory(listMode), backing(std::move(backing)), header(header), ownEntry(ownEntry) {}
|
||||||
|
|
||||||
std::vector<RomFileSystemDirectory::Entry> RomFileSystemDirectory::Read() {
|
std::vector<RomFileSystemDirectory::Entry> RomFileSystemDirectory::Read() {
|
||||||
std::vector<Entry> contents;
|
std::vector<Entry> contents;
|
||||||
|
@ -87,7 +87,7 @@ namespace skyline {
|
|||||||
std::shared_ptr<Backing> backing;
|
std::shared_ptr<Backing> backing;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RomFileSystemDirectory(const std::shared_ptr<Backing> &backing, const RomFileSystem::RomFsHeader &header, const RomFileSystem::RomFsDirectoryEntry &ownEntry, ListMode listMode);
|
RomFileSystemDirectory(std::shared_ptr<Backing> backing, const RomFileSystem::RomFsHeader &header, const RomFileSystem::RomFsDirectoryEntry &ownEntry, ListMode listMode);
|
||||||
|
|
||||||
std::vector<Entry> Read();
|
std::vector<Entry> Read();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user