summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/app/build.gradle.kts13
-rw-r--r--src/android/build.gradle.kts9
-rw-r--r--src/android/gradle.properties27
-rw-r--r--src/android/gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--src/common/android/android_common.h2
-rw-r--r--src/core/arm/nce/arm_nce.cpp123
-rw-r--r--src/core/arm/nce/arm_nce.h35
-rw-r--r--src/core/hardware_properties.h3
8 files changed, 40 insertions, 174 deletions
diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts
index 1e5cbeed6..23f905abb 100644
--- a/src/android/app/build.gradle.kts
+++ b/src/android/app/build.gradle.kts
@@ -11,9 +11,9 @@ plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("kotlin-parcelize")
- kotlin("plugin.serialization") version "2.1.20-RC"
+ kotlin("plugin.serialization") version "2.1.20-RC2"
id("androidx.navigation.safeargs.kotlin")
- id("org.jlleitschuh.gradle.ktlint") version "12.1.2"
+ id("org.jlleitschuh.gradle.ktlint") version "12.2.0"
id("com.github.triplet.play") version "3.12.1"
}
@@ -238,7 +238,7 @@ dependencies {
implementation("androidx.core:core-ktx:1.15.0")
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("androidx.recyclerview:recyclerview:1.4.0")
- implementation("androidx.constraintlayout:constraintlayout:2.2.0")
+ implementation("androidx.constraintlayout:constraintlayout:2.2.1")
implementation("androidx.fragment:fragment-ktx:1.8.6")
implementation("androidx.documentfile:documentfile:1.0.1")
implementation("com.google.android.material:material:1.12.0")
@@ -247,11 +247,12 @@ dependencies {
implementation("io.coil-kt:coil:2.7.0")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.window:window:1.3.0")
+ implementation("androidx.constraintlayout:constraintlayout:2.2.1")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
- implementation("androidx.navigation:navigation-fragment-ktx:2.8.7")
- implementation("androidx.navigation:navigation-ui-ktx:2.8.7")
+ implementation("androidx.navigation:navigation-fragment-ktx:2.8.8")
+ implementation("androidx.navigation:navigation-ui-ktx:2.8.8")
implementation("info.debatty:java-string-similarity:2.0.0")
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1")
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
}
fun runGitCommand(command: List<String>): String {
diff --git a/src/android/build.gradle.kts b/src/android/build.gradle.kts
index 9348f9f7c..128514ccf 100644
--- a/src/android/build.gradle.kts
+++ b/src/android/build.gradle.kts
@@ -1,11 +1,12 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
- id("com.android.application") version "8.8.1" apply false
- id("com.android.library") version "8.8.1" apply false
- id("org.jetbrains.kotlin.android") version "2.1.20-RC" apply false
+ id("com.android.application") version "8.9.0" apply false
+ id("com.android.library") version "8.9.0" apply false
+ id("org.jetbrains.kotlin.android") version "2.1.20-RC2" apply false
}
tasks.register("clean").configure {
@@ -17,6 +18,6 @@ buildscript {
google()
}
dependencies {
- classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.8.7")
+ classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.8.8")
}
}
diff --git a/src/android/gradle.properties b/src/android/gradle.properties
index 4fca1b576..bdfa9430e 100644
--- a/src/android/gradle.properties
+++ b/src/android/gradle.properties
@@ -1,20 +1,19 @@
-# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-# Project-wide Gradle settings.
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-# For more details on how to configure your build environment visit
+## For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
+#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xms512m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+# Default value: -Xmx1024m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+#
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+#Tue Mar 11 19:29:10 AEST 2025
+android.defaults.buildfeatures.buildconfig=true
+android.suppressUnsupportedCompileSdk=34
android.useAndroidX=true
-# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
kotlin.parallel.tasks.in.project=true
-android.defaults.buildfeatures.buildconfig=true
-
-# Android Gradle plugin 8.0.2
-android.suppressUnsupportedCompileSdk=34
+org.gradle.jvmargs=-Xms512m -Dkotlin.daemon.jvm.options\="-Xmx2048M" -Xmx2048M -XX\:MaxMetaspaceSize\=512m -XX\:+HeapDumpOnOutOfMemoryError -Dfile.encoding\=UTF-8
diff --git a/src/android/gradle/wrapper/gradle-wrapper.properties b/src/android/gradle/wrapper/gradle-wrapper.properties
index 9355b4155..e2847c820 100644
--- a/src/android/gradle/wrapper/gradle-wrapper.properties
+++ b/src/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/src/common/android/android_common.h b/src/common/android/android_common.h
index 3e58550c6..363c63cd2 100644
--- a/src/common/android/android_common.h
+++ b/src/common/android/android_common.h
@@ -1,9 +1,11 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <string>
+#include <vector>
#include <jni.h>
#include "common/common_types.h"
diff --git a/src/core/arm/nce/arm_nce.cpp b/src/core/arm/nce/arm_nce.cpp
index 491edd9f9..123b3da7e 100644
--- a/src/core/arm/nce/arm_nce.cpp
+++ b/src/core/arm/nce/arm_nce.cpp
@@ -1,5 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cinttypes>
@@ -144,55 +143,30 @@ bool ArmNce::HandleGuestAlignmentFault(GuestContext* guest_ctx, void* raw_info,
auto* fpctx = GetFloatingPointState(host_ctx);
auto& memory = guest_ctx->system->ApplicationMemory();
- // Log the alignment fault for debugging
- LOG_DEBUG(Core_ARM, "Alignment fault at PC={:X}", host_ctx.pc);
-
- // Try to handle the instruction
+ // Match and execute an instruction.
auto next_pc = MatchAndExecuteOneInstruction(memory, &host_ctx, fpctx);
if (next_pc) {
host_ctx.pc = *next_pc;
return true;
}
- // If we couldn't handle it, try to skip the instruction as a fallback
- LOG_DEBUG(Core_ARM, "Could not handle alignment fault, skipping instruction");
- host_ctx.pc += 4; // Skip to next instruction
-
- // Return true to continue execution
- return true;
+ // We couldn't handle the access.
+ return HandleFailedGuestFault(guest_ctx, raw_info, raw_context);
}
bool ArmNce::HandleGuestAccessFault(GuestContext* guest_ctx, void* raw_info, void* raw_context) {
auto* info = static_cast<siginfo_t*>(raw_info);
- const u64 fault_addr = reinterpret_cast<u64>(info->si_addr);
- auto& memory = guest_ctx->system->ApplicationMemory();
- // Get the ArmNce instance from the guest context
- ArmNce* nce = guest_ctx->parent;
-
- // Check TLB first
- if (TlbEntry* entry = nce->FindTlbEntry(fault_addr)) {
- if (!entry->writable && info->si_code == SEGV_ACCERR) {
- LOG_DEBUG(Core_ARM, "Write to read-only memory at {:X}", fault_addr);
- return HandleFailedGuestFault(guest_ctx, raw_info, raw_context);
- }
+ // Try to handle an invalid access.
+ // TODO: handle accesses which split a page?
+ const Common::ProcessAddress addr =
+ (reinterpret_cast<u64>(info->si_addr) & ~Memory::YUZU_PAGEMASK);
+ if (guest_ctx->system->ApplicationMemory().InvalidateNCE(addr, Memory::YUZU_PAGESIZE)) {
+ // We handled the access successfully and are returning to guest code.
return true;
}
- // TLB miss handling with better error checking
- if (memory.InvalidateNCE(fault_addr, Memory::CITRON_PAGESIZE)) {
- const u64 host_addr = reinterpret_cast<u64>(memory.GetPointer(fault_addr));
-
- if (host_addr) {
- nce->AddTlbEntry(fault_addr, host_addr, Memory::CITRON_PAGESIZE, true);
- return true;
- } else {
- LOG_DEBUG(Core_ARM, "Failed to get host address for guest address {:X}", fault_addr);
- }
- } else {
- LOG_DEBUG(Core_ARM, "Memory invalidation failed for address {:X}", fault_addr);
- }
-
+ // We couldn't handle the access.
return HandleFailedGuestFault(guest_ctx, raw_info, raw_context);
}
@@ -403,81 +377,4 @@ void ArmNce::InvalidateCacheRange(u64 addr, std::size_t size) {
this->ClearInstructionCache();
}
-TlbEntry* ArmNce::FindTlbEntry(u64 guest_addr) {
- std::lock_guard lock(m_tlb_mutex);
-
- // Simple linear search - more reliable than complex indexing
- for (size_t i = 0; i < TLB_SIZE; i++) {
- TlbEntry& entry = m_tlb[i];
- if (entry.valid &&
- guest_addr >= entry.guest_addr &&
- guest_addr < (entry.guest_addr + entry.size)) {
-
- // Simple access tracking - just increment counter
- if (entry.access_count < 1000) { // Prevent overflow
- entry.access_count++;
- }
- return &entry;
- }
- }
- return nullptr;
-}
-
-void ArmNce::AddTlbEntry(u64 guest_addr, u64 host_addr, u32 size, bool writable) {
- // Validate addresses before proceeding
- if (!host_addr) {
- LOG_ERROR(Core_ARM, "Invalid host address for guest address {:X}", guest_addr);
- return;
- }
-
- std::lock_guard lock(m_tlb_mutex);
-
- // First try to find an invalid entry
- size_t replace_idx = TLB_SIZE;
- for (size_t i = 0; i < TLB_SIZE; i++) {
- if (!m_tlb[i].valid) {
- replace_idx = i;
- break;
- }
- }
-
- // If no invalid entries, use simple LRU
- if (replace_idx == TLB_SIZE) {
- u32 lowest_count = UINT32_MAX;
- for (size_t i = 0; i < TLB_SIZE; i++) {
- if (m_tlb[i].access_count < lowest_count) {
- lowest_count = m_tlb[i].access_count;
- replace_idx = i;
- }
- }
- }
-
- // Safety check
- if (replace_idx >= TLB_SIZE) {
- replace_idx = 0; // Fallback to first entry if something went wrong
- }
-
- // Page align the addresses for consistency
- const u64 page_mask = size - 1;
- const u64 aligned_guest = guest_addr & ~page_mask;
- const u64 aligned_host = host_addr & ~page_mask;
-
- m_tlb[replace_idx] = {
- .guest_addr = aligned_guest,
- .host_addr = aligned_host,
- .size = size,
- .valid = true,
- .writable = writable,
- .last_access_time = 0, // Not used in simplified implementation
- .access_count = 1
- };
-}
-
-void ArmNce::InvalidateTlb() {
- std::lock_guard lock(m_tlb_mutex);
- for (auto& entry : m_tlb) {
- entry.valid = false;
- }
-}
-
} // namespace Core
diff --git a/src/core/arm/nce/arm_nce.h b/src/core/arm/nce/arm_nce.h
index 13da2c8b4..be9b304c4 100644
--- a/src/core/arm/nce/arm_nce.h
+++ b/src/core/arm/nce/arm_nce.h
@@ -1,11 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <mutex>
-#include <array>
#include "core/arm/arm_interface.h"
#include "core/arm/nce/guest_context.h"
@@ -18,21 +16,6 @@ namespace Core {
class System;
-struct TlbEntry {
- u64 guest_addr;
- u64 host_addr;
- u32 size;
- bool valid;
- bool writable;
- u64 last_access_time; // For LRU tracking
- u32 access_count; // For access frequency tracking
-};
-
-// Improved TLB configuration
-constexpr size_t TLB_SETS = 64; // Number of sets
-constexpr size_t TLB_WAYS = 8; // Ways per set
-constexpr size_t TLB_SIZE = TLB_SETS * TLB_WAYS;
-
class ArmNce final : public ArmInterface {
public:
ArmNce(System& system, bool uses_wall_clock, std::size_t core_index);
@@ -107,24 +90,6 @@ public:
// Stack for signal processing.
std::unique_ptr<u8[]> m_stack{};
-
- // Enhanced TLB implementation
- std::array<TlbEntry, TLB_SIZE> m_tlb{};
- std::mutex m_tlb_mutex;
- u64 m_tlb_access_counter{0};
-
- // TLB helper functions
- TlbEntry* FindTlbEntry(u64 guest_addr);
- void AddTlbEntry(u64 guest_addr, u64 host_addr, u32 size, bool writable);
- void InvalidateTlb();
- size_t GetTlbSetIndex(u64 guest_addr) const;
- size_t FindReplacementEntry(size_t set_start);
- void UpdateTlbEntryStats(TlbEntry& entry);
-
- // Thread context caching
- std::mutex m_context_mutex;
- Kernel::KThread* m_last_thread{nullptr};
- GuestContext m_cached_ctx{};
};
} // namespace Core
diff --git a/src/core/hardware_properties.h b/src/core/hardware_properties.h
index 191c28bb4..c0bd7fd80 100644
--- a/src/core/hardware_properties.h
+++ b/src/core/hardware_properties.h
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
@@ -13,7 +14,7 @@ namespace Core {
namespace Hardware {
-constexpr u64 BASE_CLOCK_RATE = 1'020'000'000; // Default CPU Frequency = 1020 MHz
+constexpr u64 BASE_CLOCK_RATE = 1'785'000'000; // Default CPU Frequency = 1785 MHz
constexpr u64 CNTFREQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz
constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores