0
0
mirror of https://github.com/Ishan09811/pine.git synced 2025-04-24 08:55:10 +00:00

Implement Android 15 16kib page size support (#40)

This commit is contained in:
Ishan09811 2024-12-26 20:30:27 +05:30 committed by GitHub
parent 3ff78af28e
commit 55efa7dc96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 158 additions and 133 deletions

View File

@ -19,7 +19,7 @@ jobs:
IS_BUILD_SIGNED: ${{ secrets.KEYSTORE != '' }}
UPLOAD_ARTIFACTS: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci') }}
CMAKE_VERSION: "3.22.1"
NDK_VERSION: "26.1.10909125"
NDK_VERSION: "27.2.12479018"
BUILD_TYPE: release
steps:

View File

@ -15,7 +15,7 @@ idea.module {
android {
namespace 'emu.skyline'
compileSdk 34
compileSdk 35
var isBuildSigned = (System.getenv("CI") == "true") && (System.getenv("IS_BUILD_SIGNED") == "true")
@ -23,7 +23,7 @@ android {
applicationId "io.github.pine.emu"
minSdk 29
targetSdk 34
targetSdk 35
versionCode 1
versionName "1.0.0"
@ -76,7 +76,8 @@ android {
debuggable true
externalNativeBuild {
cmake {
arguments "-DCMAKE_BUILD_TYPE=RELEASE"
arguments "-DCMAKE_BUILD_TYPE=RELEASE",
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
}
}
minifyEnabled true
@ -90,7 +91,8 @@ android {
debuggable true
externalNativeBuild {
cmake {
arguments "-DCMAKE_BUILD_TYPE=RELWITHDEBINFO"
arguments "-DCMAKE_BUILD_TYPE=RELWITHDEBINFO",
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
}
}
minifyEnabled false
@ -132,7 +134,7 @@ android {
}
/* NDK and CMake */
ndkVersion '26.1.10909125'
ndkVersion '27.2.12479018'
externalNativeBuild {
cmake {
version '3.22.1+'

@ -1 +1 @@
Subproject commit f99f0b337c97a84abdf152710a9b81e10f3d4ae8
Subproject commit e1ccbd4d4f9757856e4998b1c6087c265c62605d

View File

@ -4,6 +4,8 @@
#pragma once
#include <cstdint>
#include <unistd.h>
#include <stdexcept>
#include <variant>
namespace skyline {
@ -28,10 +30,27 @@ namespace skyline {
constexpr i64 NsInDay{86400000000000UL}; //!< The amount of nanoseconds in a day
constexpr size_t AddressSpaceSize{1ULL << 39}; //!< The size of the host CPU AS in bytes
constexpr size_t PageSize{0x1000}; //!< The size of a host page
constexpr size_t PageSizeBits{12}; //!< log2(PageSize)
static_assert(PageSize == PAGE_SIZE);
constexpr u16 TlsSlotSize{0x200};
inline size_t getDynamicPageSize() {
size_t pageSize = getpagesize();
if (pageSize == 0) {
throw std::runtime_error("Failed to retrieve page size");
}
return pageSize;
}
inline u8 getTlsSlots() {
size_t slots = getDynamicPageSize() / TlsSlotSize;
if (slots > 255) {
throw std::runtime_error("TlsSlots exceeds u8 capacity!");
}
return static_cast<u8>(slots);
}
const size_t PageSize{getDynamicPageSize()}; //!< The size of a host page
constexpr size_t PageSizeBits{12}; //!< log2(PageSize)
}
/**

View File

@ -158,8 +158,7 @@ namespace skyline {
* @return All entries overlapping with the given interval and a list of intervals they recursively cover with alignment for page-based lookup semantics
* @note This function is specifically designed for memory faulting lookups and has design-decisions that correspond to that which might not work for other uses
*/
template<size_t Alignment>
std::pair<std::vector<std::reference_wrapper<EntryType>>, std::vector<Interval>> GetAlignedRecursiveRange(Interval interval) {
std::pair<std::vector<std::reference_wrapper<EntryType>>, std::vector<Interval>> GetAlignedRecursiveRange(std::size_t Alignment, Interval interval) {
std::vector<std::reference_wrapper<EntryType>> queryEntries;
std::vector<Interval> intervals;
@ -242,9 +241,8 @@ namespace skyline {
return std::pair{queryEntries, intervals};
}
template<size_t Alignment>
std::pair<std::vector<std::reference_wrapper<EntryType>>, std::vector<Interval>> GetAlignedRecursiveRange(AddressType address) {
return GetAlignedRecursiveRange<Alignment>(Interval{address, address + 1});
std::pair<std::vector<std::reference_wrapper<EntryType>>, std::vector<Interval>> GetAlignedRecursiveRange(std::size_t Alignment, AddressType address) {
return GetAlignedRecursiveRange(Alignment, Interval{address, address + 1});
}
};
}

View File

@ -121,7 +121,7 @@ namespace skyline {
std::scoped_lock lock(trapMutex);
// Retrieve any callbacks for the page that was faulted
auto [entries, intervals]{trapMap.GetAlignedRecursiveRange<constant::PageSize>(address)};
auto [entries, intervals]{trapMap.GetAlignedRecursiveRange(constant::PageSize, address)};
if (entries.empty())
return false; // There's no callbacks associated with this page

View File

@ -5,6 +5,7 @@
#include <gpu/interconnect/command_executor.h>
#include "samplers.h"
#include <unistd.h>
#include "textures.h"
namespace skyline::gpu::interconnect {
@ -23,7 +24,7 @@ namespace skyline::gpu::interconnect {
vk::PipelineStageFlagBits dstStage,
vk::PipelineStageFlags &srcStageMask, vk::PipelineStageFlags &dstStageMask) {
if (!view) // Return a dummy buffer if the constant buffer isn't bound
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, PAGE_SIZE).buffer, 0, PAGE_SIZE};
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, getpagesize()).buffer, 0, static_cast<vk::DeviceSize>(getpagesize())};
ctx.executor.AttachBuffer(view);
view.GetBuffer()->PopulateReadBarrier(dstStage, srcStageMask, dstStageMask);
@ -47,12 +48,12 @@ namespace skyline::gpu::interconnect {
};
auto ssbo{cbuf.Read<SsboDescriptor>(ctx.executor, desc.cbuf_offset)};
if (ssbo.size == 0)
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, PAGE_SIZE).buffer, 0, PAGE_SIZE};
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, getpagesize()).buffer, 0, static_cast<vk::DeviceSize>(getpagesize())};
size_t padding{ssbo.address & (ctx.gpu.traits.minimumStorageBufferAlignment - 1)};
cachedView.Update(ctx, ssbo.address - padding, util::AlignUp(ssbo.size + padding, ctx.gpu.traits.minimumStorageBufferAlignment));
if (!cachedView.view) // Return a dummy buffer if the SSBO isn't bound
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, PAGE_SIZE).buffer, 0, PAGE_SIZE};
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, getpagesize()).buffer, 0, static_cast<vk::DeviceSize>(getpagesize())};
auto view{cachedView.view};
ctx.executor.AttachBuffer(view);

View File

@ -6,6 +6,7 @@
#include <gpu/interconnect/conversion/quads.h>
#include <gpu/interconnect/common/state_updater.h>
#include <soc/gm20b/channel.h>
#include <unistd.h>
#include "common/utils.h"
#include "maxwell_3d.h"
#include "common.h"
@ -53,7 +54,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
vk::DeviceSize size{conversion::quads::GetRequiredBufferSize(count, sizeof(u32)) + offset};
if (!quadConversionBuffer || quadConversionBuffer->size_bytes() < size) {
quadConversionBuffer = std::make_shared<memory::Buffer>(ctx.gpu.memory.AllocateBuffer(util::AlignUp(size, PAGE_SIZE)));
quadConversionBuffer = std::make_shared<memory::Buffer>(ctx.gpu.memory.AllocateBuffer(util::AlignUp(size, getpagesize())));
conversion::quads::GenerateQuadListConversionBuffer(quadConversionBuffer->cast<u32>().data(), firstVertex + count);
quadConversionBufferAttached = false;
}

View File

@ -2,14 +2,15 @@
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <gpu.h>
#include <unistd.h>
#include "megabuffer.h"
namespace skyline::gpu {
MegaBufferChunk::MegaBufferChunk(GPU &gpu) : backing{gpu.memory.AllocateBuffer(MegaBufferChunkSize)}, freeRegion{backing.subspan(PAGE_SIZE)} {}
MegaBufferChunk::MegaBufferChunk(GPU &gpu) : backing{gpu.memory.AllocateBuffer(MegaBufferChunkSize)}, freeRegion{backing.subspan(getpagesize())} {}
bool MegaBufferChunk::TryReset() {
if (cycle && cycle->Poll(true)) {
freeRegion = backing.subspan(PAGE_SIZE);
freeRegion = backing.subspan(getpagesize());
cycle = nullptr;
return true;
}
@ -24,7 +25,7 @@ namespace skyline::gpu {
std::pair<vk::DeviceSize, span<u8>> MegaBufferChunk::Allocate(const std::shared_ptr<FenceCycle> &newCycle, vk::DeviceSize size, bool pageAlign) {
if (pageAlign) {
// If page aligned data was requested then align the free
auto alignedFreeBase{util::AlignUp(static_cast<size_t>(freeRegion.data() - backing.data()), PAGE_SIZE)};
auto alignedFreeBase{util::AlignUp(static_cast<size_t>(freeRegion.data() - backing.data()), getpagesize())};
freeRegion = backing.subspan(alignedFreeBase);
}

View File

@ -78,11 +78,14 @@ namespace skyline::gpu {
try {
choreographerLooper = ALooper_prepare(0);
AChoreographer_postFrameCallback64(AChoreographer_getInstance(), reinterpret_cast<AChoreographer_frameCallback64>(&ChoreographerCallback), this);
while (ALooper_pollAll(-1, nullptr, nullptr, nullptr) == ALOOPER_POLL_WAKE && !choreographerStop) {
while (ALooper_pollOnce(-1, nullptr, nullptr, nullptr) == ALOOPER_POLL_WAKE && !choreographerStop) {
while (paused.load(std::memory_order_acquire)) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
} catch (const signal::SignalException &e) {
LOGE("{}\nStack Trace:{}", e.what(), state.loader->GetStackTrace(e.frames));
if (state.process)

View File

@ -12,8 +12,7 @@
namespace skyline {
namespace constant {
constexpr u16 TlsSlotSize{0x200}; //!< The size of a single TLS slot
constexpr u8 TlsSlots{constant::PageSize / TlsSlotSize}; //!< The amount of TLS slots in a single page
const u8 TlsSlots{constant::getTlsSlots()}; //!< The amount of TLS slots in a single page
constexpr KHandle BaseHandleIndex{0xD000}; //!< The index of the base handle
}

View File

@ -7,6 +7,7 @@
#include <os.h>
#include <kernel/types/KProcess.h>
#include <kernel/memory.h>
#include <unistd.h>
#include "loader.h"
namespace skyline::loader {
@ -45,7 +46,7 @@ namespace skyline::loader {
size_t hookSize{0};
if (enableSymbolHooking && dynamicallyLinked) {
executableSymbols = hle::GetExecutableSymbols(dynsym.cast<Elf64_Sym>(), dynstr);
hookSize = util::AlignUp(state.nce->GetHookSectionSize(executableSymbols), PAGE_SIZE);
hookSize = util::AlignUp(state.nce->GetHookSectionSize(executableSymbols), getpagesize());
}
// Reserve patch + hook size only if we need to patch