From 0cc266ff190b2594304271f1635b624ef008036f Mon Sep 17 00:00:00 2001 From: Mary Date: Mon, 12 Jun 2023 12:29:41 +0200 Subject: [PATCH 01/10] infra: Add PR triage action (#5293) This is a bare minimal triage action that handle big categories. In the future we could also label all services correctly but I didn't felt this was required for a first iteration. --- .github/assign/audio.yml | 8 ++++++ .github/assign/cpu.yml | 11 +++++++ .github/assign/global.yml | 4 +++ .github/assign/gpu.yml | 10 +++++++ .github/assign/gui.yml | 11 +++++++ .github/assign/horizon.yml | 11 +++++++ .github/assign/infra.yml | 9 ++++++ .github/labeler.yml | 33 +++++++++++++++++++++ .github/workflows/pr_triage.yml | 51 +++++++++++++++++++++++++++++++++ 9 files changed, 148 insertions(+) create mode 100644 .github/assign/audio.yml create mode 100644 .github/assign/cpu.yml create mode 100644 .github/assign/global.yml create mode 100644 .github/assign/gpu.yml create mode 100644 .github/assign/gui.yml create mode 100644 .github/assign/horizon.yml create mode 100644 .github/assign/infra.yml create mode 100644 .github/labeler.yml create mode 100644 .github/workflows/pr_triage.yml diff --git a/.github/assign/audio.yml b/.github/assign/audio.yml new file mode 100644 index 000000000..337007d39 --- /dev/null +++ b/.github/assign/audio.yml @@ -0,0 +1,8 @@ +addReviewers: true + +reviewers: + - marysaka + +filterLabels: + include: + - audio \ No newline at end of file diff --git a/.github/assign/cpu.yml b/.github/assign/cpu.yml new file mode 100644 index 000000000..da824bdc3 --- /dev/null +++ b/.github/assign/cpu.yml @@ -0,0 +1,11 @@ +addReviewers: true + +reviewers: + - gdkchan + - riperiperi + - marysaka + - LDj3SNuD + +filterLabels: + include: + - cpu \ No newline at end of file diff --git a/.github/assign/global.yml b/.github/assign/global.yml new file mode 100644 index 000000000..afd5ce445 --- /dev/null +++ b/.github/assign/global.yml @@ -0,0 +1,4 @@ +addReviewers: true + +reviewers: + - Developers \ No newline at end of file diff --git a/.github/assign/gpu.yml b/.github/assign/gpu.yml new file mode 100644 index 000000000..b96d9d87d --- /dev/null +++ b/.github/assign/gpu.yml @@ -0,0 +1,10 @@ +addReviewers: true + +reviewers: + - gdkchan + - riperiperi + - marysaka + +filterLabels: + include: + - gpu \ No newline at end of file diff --git a/.github/assign/gui.yml b/.github/assign/gui.yml new file mode 100644 index 000000000..9731ea5bd --- /dev/null +++ b/.github/assign/gui.yml @@ -0,0 +1,11 @@ +addReviewers: true + +reviewers: + - Ack77 + - emmauss + - TSRBerry + - marysaka + +filterLabels: + include: + - gui \ No newline at end of file diff --git a/.github/assign/horizon.yml b/.github/assign/horizon.yml new file mode 100644 index 000000000..966382b29 --- /dev/null +++ b/.github/assign/horizon.yml @@ -0,0 +1,11 @@ +addReviewers: true + +reviewers: + - gdkchan + - Ack77 + - marysaka + - TSRBerry + +filterLabels: + include: + - horizon \ No newline at end of file diff --git a/.github/assign/infra.yml b/.github/assign/infra.yml new file mode 100644 index 000000000..d319fef19 --- /dev/null +++ b/.github/assign/infra.yml @@ -0,0 +1,9 @@ +addReviewers: true + +reviewers: + - marysaka + - TSRBerry + +filterLabels: + include: + - infra \ No newline at end of file diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000..7b8ae302d --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,33 @@ +audio: 'src/Ryujinx.Audio*' + +cpu: + - 'src/ARMeilleure//*' + - 'src/Ryujinx.Cpu/*' + - 'src/Ryujinx.Memory/*' + +gpu: + - 'src/Ryujinx.Graphics.*' + - 'src/Spv.Generator/*' + - 'src/Ryujinx.ShaderTools/*' + +'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/*' +'graphics-backend:vulkan': + - 'src/Ryujinx.Graphics.Vulkan/*' + - 'src/Spv.Generator/*' + +gui: + - 'src/Ryujinx/*' + - 'src/Ryujinx.Ui.Common/*' + - 'src/Ryujinx.Ui.LocaleGenerator/*' + - 'src/Ryujinx.Ava/*' + +horizon: + - 'src/Ryujinx.HLE/*' + - 'src/Ryujinx.Horizon*' + +kernel: 'src/Ryujinx.HLE/HOS/Kernel/*' + +infra: + - '.github/*' + - 'distribution/*' + - 'Directory.Packages.props' diff --git a/.github/workflows/pr_triage.yml b/.github/workflows/pr_triage.yml new file mode 100644 index 000000000..32a88480b --- /dev/null +++ b/.github/workflows/pr_triage.yml @@ -0,0 +1,51 @@ +name: "Pull Request Triage" +on: +- pull_request_target + +jobs: + triage: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: Update labels based on changes + uses: actions/labeler@v4 + with: + sync-labels: true + dot: true + + - uses: kentaro-m/auto-assign-action@v1.2.5 + with: + configuration-path: '.github/assign/audio.yml' + if: github.event.action == 'opened' + + - uses: kentaro-m/auto-assign-action@v1.2.5 + with: + configuration-path: '.github/assign/cpu.yml' + if: github.event.action == 'opened' + + - uses: kentaro-m/auto-assign-action@v1.2.5 + with: + configuration-path: '.github/assign/gpu.yml' + if: github.event.action == 'opened' + + - uses: kentaro-m/auto-assign-action@v1.2.5 + with: + configuration-path: '.github/assign/gui.yml' + if: github.event.action == 'opened' + + - uses: kentaro-m/auto-assign-action@v1.2.5 + with: + configuration-path: '.github/assign/horizon.yml' + if: github.event.action == 'opened' + + - uses: kentaro-m/auto-assign-action@v1.2.5 + with: + configuration-path: '.github/assign/infra.yml' + if: github.event.action == 'opened' + + - uses: kentaro-m/auto-assign-action@v1.2.5 + with: + configuration-path: '.github/assign/global.yml' + if: github.event.action == 'opened' From 915a0f7173299c0b8a2c285f4e90b34cdae80811 Mon Sep 17 00:00:00 2001 From: Steveice10 <1269164+Steveice10@users.noreply.github.com> Date: Mon, 12 Jun 2023 08:33:13 -0700 Subject: [PATCH 02/10] hle: Stub IHidbusServer.GetBusHandle (#5284) --- .../HOS/Services/Hid/IHidbusServer.cs | 23 ++++++++++++++++++- .../HOS/Services/Hid/Types/Npad/BusHandle.cs | 14 +++++++++++ .../HOS/Services/Hid/Types/Npad/BusType.cs | 9 ++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs create mode 100644 src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs index bfd1d4dcd..eec5292f5 100644 --- a/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs +++ b/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs @@ -1,8 +1,29 @@ -namespace Ryujinx.HLE.HOS.Services.Hid +using Ryujinx.Common; +using Ryujinx.Common.Logging; + +namespace Ryujinx.HLE.HOS.Services.Hid { [Service("hidbus")] class IHidbusServer : IpcService { public IHidbusServer(ServiceCtx context) { } + + [CommandCmif(1)] + // GetBusHandle(nn::hid::NpadIdType, nn::hidbus::BusType, nn::applet::AppletResourceUserId) -> (bool HasHandle, nn::hidbus::BusHandle) + public ResultCode GetBusHandle(ServiceCtx context) + { + NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadInt32(); + context.RequestData.BaseStream.Position += 4; // Padding + BusType busType = (BusType)context.RequestData.ReadInt64(); + long appletResourceUserId = context.RequestData.ReadInt64(); + + context.ResponseData.Write(false); + context.ResponseData.BaseStream.Position += 7; // Padding + context.ResponseData.WriteStruct(new BusHandle()); + + Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadIdType, busType, appletResourceUserId }); + + return ResultCode.Success; + } } } \ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs new file mode 100644 index 000000000..936ee68c4 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs @@ -0,0 +1,14 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Hid +{ + [StructLayout(LayoutKind.Sequential)] + struct BusHandle + { + public int AbstractedPadId; + public byte InternalIndex; + public byte PlayerNumber; + public byte BusTypeId; + public byte IsValid; + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs new file mode 100644 index 000000000..41852365b --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.HLE.HOS.Services.Hid +{ + public enum BusType : long + { + LeftJoyRail = 0, + RightJoyRail = 1, + InternalBus = 2 + } +} From 5a02433080f194407a891283c1b12275944a3d9f Mon Sep 17 00:00:00 2001 From: TSRBerry <20988865+TSRBerry@users.noreply.github.com> Date: Mon, 12 Jun 2023 20:42:27 +0200 Subject: [PATCH 03/10] infra: Fix PR triage workflow glob patterns (#5297) * Use glob patterns to match file paths * Update ignored paths for releases * Adjust build.yml as well * Add names to auto-assign steps * Fix developer team name * Allow build workflows to run if workflows changed --- .github/assign/global.yml | 2 +- .github/labeler.yml | 40 ++++++++++++++++----------------- .github/workflows/build.yml | 19 ++++++---------- .github/workflows/pr_triage.yml | 25 +++++++++++++-------- .github/workflows/release.yml | 5 +++-- 5 files changed, 47 insertions(+), 44 deletions(-) diff --git a/.github/assign/global.yml b/.github/assign/global.yml index afd5ce445..53a9af429 100644 --- a/.github/assign/global.yml +++ b/.github/assign/global.yml @@ -1,4 +1,4 @@ addReviewers: true reviewers: - - Developers \ No newline at end of file + - Ryujinx/developers \ No newline at end of file diff --git a/.github/labeler.yml b/.github/labeler.yml index 7b8ae302d..587830be1 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,33 +1,33 @@ -audio: 'src/Ryujinx.Audio*' +audio: 'src/Ryujinx.Audio*/**' cpu: - - 'src/ARMeilleure//*' - - 'src/Ryujinx.Cpu/*' - - 'src/Ryujinx.Memory/*' + - 'src/ARMeilleure/**' + - 'src/Ryujinx.Cpu/**' + - 'src/Ryujinx.Memory/**' gpu: - - 'src/Ryujinx.Graphics.*' - - 'src/Spv.Generator/*' - - 'src/Ryujinx.ShaderTools/*' + - 'src/Ryujinx.Graphics.*/**' + - 'src/Spv.Generator/**' + - 'src/Ryujinx.ShaderTools/**' -'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/*' +'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/**' 'graphics-backend:vulkan': - - 'src/Ryujinx.Graphics.Vulkan/*' - - 'src/Spv.Generator/*' + - 'src/Ryujinx.Graphics.Vulkan/**' + - 'src/Spv.Generator/**' gui: - - 'src/Ryujinx/*' - - 'src/Ryujinx.Ui.Common/*' - - 'src/Ryujinx.Ui.LocaleGenerator/*' - - 'src/Ryujinx.Ava/*' + - 'src/Ryujinx/**' + - 'src/Ryujinx.Ui.Common/**' + - 'src/Ryujinx.Ui.LocaleGenerator/**' + - 'src/Ryujinx.Ava/**' horizon: - - 'src/Ryujinx.HLE/*' - - 'src/Ryujinx.Horizon*' + - 'src/Ryujinx.HLE/**' + - 'src/Ryujinx.Horizon*/**' -kernel: 'src/Ryujinx.HLE/HOS/Kernel/*' +kernel: 'src/Ryujinx.HLE/HOS/Kernel/**' infra: - - '.github/*' - - 'distribution/*' - - 'Directory.Packages.props' + - '.github/**' + - 'distribution/**' + - 'Directory.Packages.props' \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 97db387f0..886bb0444 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,20 +3,15 @@ name: Build job on: workflow_dispatch: inputs: {} - #push: - # branches: [ master ] - # paths-ignore: - # - '.github/*' - # - '.github/ISSUE_TEMPLATE/**' - # - '*.yml' - # - 'README.md' pull_request: branches: [ master ] - paths-ignore: - - '.github/*' - - '.github/ISSUE_TEMPLATE/**' - - '*.yml' - - 'README.md' + paths: + - '!.github/**' + - '!*.yml' + - '!*.json' + - '!*.config' + - '!README.md' + - '.github/workflows/*.yml' concurrency: group: pr-checks-${{ github.event.number }} diff --git a/.github/workflows/pr_triage.yml b/.github/workflows/pr_triage.yml index 32a88480b..8a27e3c95 100644 --- a/.github/workflows/pr_triage.yml +++ b/.github/workflows/pr_triage.yml @@ -1,6 +1,6 @@ name: "Pull Request Triage" on: -- pull_request_target + pull_request_target: jobs: triage: @@ -15,37 +15,44 @@ jobs: sync-labels: true dot: true - - uses: kentaro-m/auto-assign-action@v1.2.5 + - name: Auto Assign [Audio] + uses: kentaro-m/auto-assign-action@v1 with: configuration-path: '.github/assign/audio.yml' if: github.event.action == 'opened' - - uses: kentaro-m/auto-assign-action@v1.2.5 + - name: Auto Assign [CPU] + uses: kentaro-m/auto-assign-action@v1 with: configuration-path: '.github/assign/cpu.yml' if: github.event.action == 'opened' - - uses: kentaro-m/auto-assign-action@v1.2.5 + - name: Auto Assign [GPU] + uses: kentaro-m/auto-assign-action@v1 with: configuration-path: '.github/assign/gpu.yml' if: github.event.action == 'opened' - - uses: kentaro-m/auto-assign-action@v1.2.5 + - name: Auto Assign [GUI] + uses: kentaro-m/auto-assign-action@v1 with: configuration-path: '.github/assign/gui.yml' if: github.event.action == 'opened' - - uses: kentaro-m/auto-assign-action@v1.2.5 + - name: Auto Assign [Horizon] + uses: kentaro-m/auto-assign-action@v1 with: configuration-path: '.github/assign/horizon.yml' if: github.event.action == 'opened' - - uses: kentaro-m/auto-assign-action@v1.2.5 + - name: Auto Assign [Infra] + uses: kentaro-m/auto-assign-action@v1 with: configuration-path: '.github/assign/infra.yml' if: github.event.action == 'opened' - - uses: kentaro-m/auto-assign-action@v1.2.5 + - name: Auto Assign [Global] + uses: kentaro-m/auto-assign-action@v1 with: configuration-path: '.github/assign/global.yml' - if: github.event.action == 'opened' + if: github.event.action == 'opened' \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 98ba34822..63e6d0187 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,9 +6,10 @@ on: push: branches: [ master ] paths-ignore: - - '.github/*' - - '.github/ISSUE_TEMPLATE/**' + - '.github/**' - '*.yml' + - '*.json' + - '*.config' - 'README.md' concurrency: release From 52aa4b6c22ce697f82ae59c6c6610eadf6bbeacf Mon Sep 17 00:00:00 2001 From: TSRBerry <20988865+TSRBerry@users.noreply.github.com> Date: Mon, 12 Jun 2023 21:57:07 +0200 Subject: [PATCH 04/10] Fix action version (#5299) --- .github/workflows/pr_triage.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/pr_triage.yml b/.github/workflows/pr_triage.yml index 8a27e3c95..27a00f101 100644 --- a/.github/workflows/pr_triage.yml +++ b/.github/workflows/pr_triage.yml @@ -16,43 +16,43 @@ jobs: dot: true - name: Auto Assign [Audio] - uses: kentaro-m/auto-assign-action@v1 + uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/audio.yml' if: github.event.action == 'opened' - name: Auto Assign [CPU] - uses: kentaro-m/auto-assign-action@v1 + uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/cpu.yml' if: github.event.action == 'opened' - name: Auto Assign [GPU] - uses: kentaro-m/auto-assign-action@v1 + uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/gpu.yml' if: github.event.action == 'opened' - name: Auto Assign [GUI] - uses: kentaro-m/auto-assign-action@v1 + uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/gui.yml' if: github.event.action == 'opened' - name: Auto Assign [Horizon] - uses: kentaro-m/auto-assign-action@v1 + uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/horizon.yml' if: github.event.action == 'opened' - name: Auto Assign [Infra] - uses: kentaro-m/auto-assign-action@v1 + uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/infra.yml' if: github.event.action == 'opened' - name: Auto Assign [Global] - uses: kentaro-m/auto-assign-action@v1 + uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/global.yml' if: github.event.action == 'opened' \ No newline at end of file From cf4c78b9c825f61ff3ee83eff88442a149ae01d9 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 12 Jun 2023 21:12:06 -0300 Subject: [PATCH 05/10] Make LM skip instead of crashing for invalid messages (#5290) --- src/Ryujinx.Common/Memory/SpanReader.cs | 18 ++++++++ .../LogManager/Ipc/LmLogger.cs | 45 +++++++++++++------ 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/Ryujinx.Common/Memory/SpanReader.cs b/src/Ryujinx.Common/Memory/SpanReader.cs index 673932d0b..9a1a0a3f0 100644 --- a/src/Ryujinx.Common/Memory/SpanReader.cs +++ b/src/Ryujinx.Common/Memory/SpanReader.cs @@ -24,6 +24,24 @@ namespace Ryujinx.Common.Memory return value; } + public bool TryRead(out T value) where T : unmanaged + { + int valueSize = Unsafe.SizeOf(); + + if (valueSize > _input.Length) + { + value = default; + + return false; + } + + value = MemoryMarshal.Cast(_input)[0]; + + _input = _input.Slice(valueSize); + + return true; + } + public ReadOnlySpan GetSpan(int size) { ReadOnlySpan data = _input.Slice(0, size); diff --git a/src/Ryujinx.Horizon/LogManager/Ipc/LmLogger.cs b/src/Ryujinx.Horizon/LogManager/Ipc/LmLogger.cs index e930bdd75..88dddef5e 100644 --- a/src/Ryujinx.Horizon/LogManager/Ipc/LmLogger.cs +++ b/src/Ryujinx.Horizon/LogManager/Ipc/LmLogger.cs @@ -17,7 +17,7 @@ namespace Ryujinx.Horizon.LogManager.Ipc private const int MessageLengthLimit = 5000; private readonly LogService _log; - private readonly ulong _pid; + private readonly ulong _pid; private LogPacket _logPacket; @@ -74,8 +74,12 @@ namespace Ryujinx.Horizon.LogManager.Ipc private bool LogImpl(ReadOnlySpan message) { - SpanReader reader = new(message); - LogPacketHeader header = reader.Read(); + SpanReader reader = new(message); + + if (!reader.TryRead(out LogPacketHeader header)) + { + return true; + } bool isHeadPacket = (header.Flags & LogPacketFlags.IsHead) != 0; bool isTailPacket = (header.Flags & LogPacketFlags.IsTail) != 0; @@ -84,8 +88,10 @@ namespace Ryujinx.Horizon.LogManager.Ipc while (reader.Length > 0) { - int type = ReadUleb128(ref reader); - int size = ReadUleb128(ref reader); + if (!TryReadUleb128(ref reader, out int type) || !TryReadUleb128(ref reader, out int size)) + { + return true; + } LogDataChunkKey key = (LogDataChunkKey)type; @@ -101,15 +107,24 @@ namespace Ryujinx.Horizon.LogManager.Ipc } else if (key == LogDataChunkKey.Line) { - _logPacket.Line = reader.Read(); + if (!reader.TryRead(out _logPacket.Line)) + { + return true; + } } else if (key == LogDataChunkKey.DropCount) { - _logPacket.DropCount = reader.Read(); + if (!reader.TryRead(out _logPacket.DropCount)) + { + return true; + } } else if (key == LogDataChunkKey.Time) { - _logPacket.Time = reader.Read(); + if (!reader.TryRead(out _logPacket.Time)) + { + return true; + } } else if (key == LogDataChunkKey.Message) { @@ -154,23 +169,25 @@ namespace Ryujinx.Horizon.LogManager.Ipc return isTailPacket; } - private static int ReadUleb128(ref SpanReader reader) + private static bool TryReadUleb128(ref SpanReader reader, out int result) { - int result = 0; - int count = 0; - + result = 0; + int count = 0; byte encoded; do { - encoded = reader.Read(); + if (!reader.TryRead(out encoded)) + { + return false; + } result += (encoded & 0x7F) << (7 * count); count++; } while ((encoded & 0x80) != 0); - return result; + return true; } } } \ No newline at end of file From 5bd2c58ad63ba42cb22d1525585efeacaef10c46 Mon Sep 17 00:00:00 2001 From: mmdurrant Date: Mon, 12 Jun 2023 18:36:40 -0600 Subject: [PATCH 06/10] UI: Correctly set 'shell/open/command; registry key for file associations (#5244) * Correctly set 'shell/open/command; registry key for file associations * File association fixes * 'using' statements instead of blocks * Idempotent unregistration * Single "hey shell, we changed file associations" notification at the end instead of 1 for every operation, speeds things up greatly. * Adapt and fix Linux specific function as well --------- Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com> --- .../Helper/FileAssociationHelper.cs | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs b/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs index 4f4b25245..542db9a7e 100644 --- a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs +++ b/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs @@ -11,10 +11,10 @@ namespace Ryujinx.Ui.Common.Helper { public static partial class FileAssociationHelper { - private static string[] _fileExtensions = new string[] { ".nca", ".nro", ".nso", ".nsp", ".xci" }; + private static readonly string[] _fileExtensions = { ".nca", ".nro", ".nso", ".nsp", ".xci" }; [SupportedOSPlatform("linux")] - private static string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime"); + private static readonly string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime"); private const int SHCNE_ASSOCCHANGED = 0x8000000; private const int SHCNF_FLUSH = 0x1000; @@ -32,7 +32,7 @@ namespace Ryujinx.Ui.Common.Helper { string installKeyword = uninstall ? "uninstall" : "install"; - if (!AreMimeTypesRegisteredLinux()) + if ((uninstall && AreMimeTypesRegisteredLinux()) || (!uninstall && !AreMimeTypesRegisteredLinux())) { string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml"); string additionalArgs = !uninstall ? "--novendor" : ""; @@ -81,9 +81,9 @@ namespace Ryujinx.Ui.Common.Helper return false; } - key.OpenSubKey(@"shell\open\command"); + var openCmd = key.OpenSubKey(@"shell\open\command"); - string keyValue = (string)key.GetValue(""); + string keyValue = (string)openCmd.GetValue(""); return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName)); } @@ -107,30 +107,31 @@ namespace Ryujinx.Ui.Common.Helper if (uninstall) { + // If the types don't already exist, there's nothing to do and we can call this operation successful. if (!AreMimeTypesRegisteredWindows()) { - return false; + return true; } - + Logger.Debug?.Print(LogClass.Application, $"Removing type association {ext}"); Registry.CurrentUser.DeleteSubKeyTree(keyString); + Logger.Debug?.Print(LogClass.Application, $"Removed type association {ext}"); } else { - RegistryKey key = Registry.CurrentUser.CreateSubKey(keyString); + using var key = Registry.CurrentUser.CreateSubKey(keyString); + if (key is null) { return false; } - key.CreateSubKey(@"shell\open\command"); + Logger.Debug?.Print(LogClass.Application, $"Adding type association {ext}"); + using var openCmd = key.CreateSubKey(@"shell\open\command"); + openCmd.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\""); + Logger.Debug?.Print(LogClass.Application, $"Added type association {ext}"); - key.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\""); - key.Close(); } - // Notify Explorer the file association has been changed. - SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero); - return true; } @@ -141,6 +142,9 @@ namespace Ryujinx.Ui.Common.Helper registered |= RegisterExtension(ext, uninstall); } + // Notify Explorer the file association has been changed. + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero); + return registered; } From 4a27d29412f68d3926da3e3fd1d1619914b1b5fc Mon Sep 17 00:00:00 2001 From: Mary Date: Tue, 13 Jun 2023 11:51:22 +0200 Subject: [PATCH 07/10] infra: Sync paths-ignore with release job and attempt to fix review assign --- .github/workflows/build.yml | 13 ++++++------- .github/workflows/pr_triage.yml | 12 ++++-------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 886bb0444..bf8fd000a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,13 +5,12 @@ on: inputs: {} pull_request: branches: [ master ] - paths: - - '!.github/**' - - '!*.yml' - - '!*.json' - - '!*.config' - - '!README.md' - - '.github/workflows/*.yml' + paths-ignore: + - '.github/**' + - '*.yml' + - '*.json' + - '*.config' + - 'README.md' concurrency: group: pr-checks-${{ github.event.number }} diff --git a/.github/workflows/pr_triage.yml b/.github/workflows/pr_triage.yml index 27a00f101..e32dd27ad 100644 --- a/.github/workflows/pr_triage.yml +++ b/.github/workflows/pr_triage.yml @@ -1,13 +1,16 @@ name: "Pull Request Triage" on: pull_request_target: + types: [opened, ready_for_review] jobs: triage: permissions: contents: read pull-requests: write + runs-on: ubuntu-latest + steps: - name: Update labels based on changes uses: actions/labeler@v4 @@ -19,40 +22,33 @@ jobs: uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/audio.yml' - if: github.event.action == 'opened' - name: Auto Assign [CPU] uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/cpu.yml' - if: github.event.action == 'opened' - name: Auto Assign [GPU] uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/gpu.yml' - if: github.event.action == 'opened' - name: Auto Assign [GUI] uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/gui.yml' - if: github.event.action == 'opened' - name: Auto Assign [Horizon] uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/horizon.yml' - if: github.event.action == 'opened' - name: Auto Assign [Infra] uses: kentaro-m/auto-assign-action@v1.2.5 with: configuration-path: '.github/assign/infra.yml' - if: github.event.action == 'opened' - name: Auto Assign [Global] uses: kentaro-m/auto-assign-action@v1.2.5 with: - configuration-path: '.github/assign/global.yml' - if: github.event.action == 'opened' \ No newline at end of file + configuration-path: '.github/assign/global.yml' \ No newline at end of file From 4d804ed45e1c00b74714089e26f941e71a1c8c45 Mon Sep 17 00:00:00 2001 From: Kurochi51 Date: Tue, 13 Jun 2023 21:47:33 +0300 Subject: [PATCH 08/10] Mod Loader: Stop loading mods from folders that don't exactly match titleId (#5298) * Stop loading mods from folders that don't exactly match titleId * What the worst that can happen? --- src/Ryujinx.HLE/HOS/ModLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx.HLE/HOS/ModLoader.cs b/src/Ryujinx.HLE/HOS/ModLoader.cs index ac983cfe5..243510967 100644 --- a/src/Ryujinx.HLE/HOS/ModLoader.cs +++ b/src/Ryujinx.HLE/HOS/ModLoader.cs @@ -154,7 +154,7 @@ namespace Ryujinx.HLE.HOS } private static DirectoryInfo FindTitleDir(DirectoryInfo contentsDir, string titleId) - => contentsDir.EnumerateDirectories($"{titleId}*", DirEnumOptions).FirstOrDefault(); + => contentsDir.EnumerateDirectories(titleId, DirEnumOptions).FirstOrDefault(); private static void AddModsFromDirectory(ModCache mods, DirectoryInfo dir, string titleId) { From 105c9712c1cf8400b3ff34c3a69a8af81ee4431e Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 14 Jun 2023 00:57:02 -0300 Subject: [PATCH 09/10] Fix Arm32 double to int/uint conversion on Arm64 (#5292) * Fix Arm32 double to int/uint conversion on Arm64 * PPTC version bump --- .../Instructions/InstEmitSimdCvt32.cs | 74 ++++++++++++++----- .../Instructions/InstEmitSimdHelper32Arm64.cs | 12 ++- src/ARMeilleure/Translation/PTC/Ptc.cs | 2 +- 3 files changed, 64 insertions(+), 24 deletions(-) diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs index 33ae83df6..bec36e2d6 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs @@ -165,7 +165,7 @@ namespace ARMeilleure.Instructions { Operand m = GetVecA32(op.Vm >> 1); - Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, doubleSize); + Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true); Intrinsic inst = (unsigned ? Intrinsic.Arm64FcvtzuGp : Intrinsic.Arm64FcvtzsGp) | Intrinsic.Arm64VDouble; @@ -175,7 +175,7 @@ namespace ARMeilleure.Instructions } else { - InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS); + InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS, false); } } else if (!roundWithFpscr && Optimizations.UseSse41) @@ -260,28 +260,64 @@ namespace ARMeilleure.Instructions if (Optimizations.UseAdvSimd) { - if (unsigned) + bool doubleSize = floatSize == OperandType.FP64; + + if (doubleSize) { - inst = rm switch { - 0b00 => Intrinsic.Arm64FcvtauS, - 0b01 => Intrinsic.Arm64FcvtnuS, - 0b10 => Intrinsic.Arm64FcvtpuS, - 0b11 => Intrinsic.Arm64FcvtmuS, - _ => throw new ArgumentOutOfRangeException(nameof(rm)) - }; + Operand m = GetVecA32(op.Vm >> 1); + + Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true); + + if (unsigned) + { + inst = rm switch { + 0b00 => Intrinsic.Arm64FcvtauGp, + 0b01 => Intrinsic.Arm64FcvtnuGp, + 0b10 => Intrinsic.Arm64FcvtpuGp, + 0b11 => Intrinsic.Arm64FcvtmuGp, + _ => throw new ArgumentOutOfRangeException(nameof(rm)) + }; + } + else + { + inst = rm switch { + 0b00 => Intrinsic.Arm64FcvtasGp, + 0b01 => Intrinsic.Arm64FcvtnsGp, + 0b10 => Intrinsic.Arm64FcvtpsGp, + 0b11 => Intrinsic.Arm64FcvtmsGp, + _ => throw new ArgumentOutOfRangeException(nameof(rm)) + }; + } + + Operand asInteger = context.AddIntrinsicInt(inst | Intrinsic.Arm64VDouble, toConvert); + + InsertScalar(context, op.Vd, asInteger); } else { - inst = rm switch { - 0b00 => Intrinsic.Arm64FcvtasS, - 0b01 => Intrinsic.Arm64FcvtnsS, - 0b10 => Intrinsic.Arm64FcvtpsS, - 0b11 => Intrinsic.Arm64FcvtmsS, - _ => throw new ArgumentOutOfRangeException(nameof(rm)) - }; - } + if (unsigned) + { + inst = rm switch { + 0b00 => Intrinsic.Arm64FcvtauS, + 0b01 => Intrinsic.Arm64FcvtnuS, + 0b10 => Intrinsic.Arm64FcvtpuS, + 0b11 => Intrinsic.Arm64FcvtmuS, + _ => throw new ArgumentOutOfRangeException(nameof(rm)) + }; + } + else + { + inst = rm switch { + 0b00 => Intrinsic.Arm64FcvtasS, + 0b01 => Intrinsic.Arm64FcvtnsS, + 0b10 => Intrinsic.Arm64FcvtpsS, + 0b11 => Intrinsic.Arm64FcvtmsS, + _ => throw new ArgumentOutOfRangeException(nameof(rm)) + }; + } - InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst); + InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst); + } } else if (Optimizations.UseSse41) { diff --git a/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs b/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs index 98236be6d..804d915c4 100644 --- a/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs +++ b/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs @@ -192,11 +192,10 @@ namespace ARMeilleure.Instructions EmitVectorTernaryOpSimd32(context, (d, n, m) => context.AddIntrinsic(inst, d, n, m)); } - public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc) + public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc, bool doubleSize) { OpCode32SimdS op = (OpCode32SimdS)context.CurrOp; - bool doubleSize = (op.Size & 1) != 0; int shift = doubleSize ? 1 : 2; Operand m = GetVecA32(op.Vm >> shift); Operand d = GetVecA32(op.Vd >> shift); @@ -215,8 +214,13 @@ namespace ARMeilleure.Instructions { OpCode32SimdS op = (OpCode32SimdS)context.CurrOp; - inst |= ((op.Size & 1) != 0 ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128; - EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m)); + EmitScalarUnaryOpF32(context, inst, (op.Size & 1) != 0); + } + + public static void EmitScalarUnaryOpF32(ArmEmitterContext context, Intrinsic inst, bool doubleSize) + { + inst |= (doubleSize ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128; + EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m), doubleSize); } public static void EmitScalarBinaryOpSimd32(ArmEmitterContext context, Func2I scalarFunc) diff --git a/src/ARMeilleure/Translation/PTC/Ptc.cs b/src/ARMeilleure/Translation/PTC/Ptc.cs index 366dea6bf..3c697bffe 100644 --- a/src/ARMeilleure/Translation/PTC/Ptc.cs +++ b/src/ARMeilleure/Translation/PTC/Ptc.cs @@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0"; - private const uint InternalVersion = 5281; //! To be incremented manually for each change to the ARMeilleure project. + private const uint InternalVersion = 5292; //! To be incremented manually for each change to the ARMeilleure project. private const string ActualDir = "0"; private const string BackupDir = "1"; From 6f28c4abadfead6fb5146caa5775dba1641bd79f Mon Sep 17 00:00:00 2001 From: Mary Date: Wed, 14 Jun 2023 18:02:41 +0200 Subject: [PATCH 10/10] test: Make tests runnable on system without 4KiB page size (#5184) * ARMeilleure: Do not hardcode 4KiB page size in JitCache * test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Memory.Tests Fix running tests on Asahi Linux with 16KiB pages. * test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Cpu Fix running tests on Asahi Linux. Test runner still crash when trying to run all test suite. * test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Cpu Fix somecrashes on Asahi Linux. * test: Ignore Vshl test on ARM64 due to unicorn crashes * test: Workaround hardcoded size on some tests Change mapping of code and data in case of non 4KiB configuration. * test: Make CpuTestT32Flow depends on code address Fix failure with different page size. * test: Disable CpuTestThumb.TestRandomTestCases when page size isn't 4KiB The test data needs to be reevaluated to take different page size into account. * Address gdkchan's comments --- src/ARMeilleure/Translation/Cache/JitCache.cs | 5 +-- src/Ryujinx.Tests.Memory/Tests.cs | 35 +++++++++++-------- src/Ryujinx.Tests/Cpu/CpuTest.cs | 24 +++++++++---- src/Ryujinx.Tests/Cpu/CpuTest32.cs | 24 +++++++++---- src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs | 34 +++++++++--------- src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs | 6 ++++ src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs | 6 ++-- src/Ryujinx.Tests/Cpu/CpuTestThumb.cs | 6 ++++ 8 files changed, 93 insertions(+), 47 deletions(-) diff --git a/src/ARMeilleure/Translation/Cache/JitCache.cs b/src/ARMeilleure/Translation/Cache/JitCache.cs index daa2eeac2..aa732d0ae 100644 --- a/src/ARMeilleure/Translation/Cache/JitCache.cs +++ b/src/ARMeilleure/Translation/Cache/JitCache.cs @@ -2,6 +2,7 @@ using ARMeilleure.CodeGen; using ARMeilleure.CodeGen.Unwinding; using ARMeilleure.Memory; using ARMeilleure.Native; +using Ryujinx.Memory; using System; using System.Collections.Generic; using System.Diagnostics; @@ -12,8 +13,8 @@ namespace ARMeilleure.Translation.Cache { static partial class JitCache { - private const int PageSize = 4 * 1024; - private const int PageMask = PageSize - 1; + private static readonly int PageSize = (int)MemoryBlock.GetPageSize(); + private static readonly int PageMask = PageSize - 1; private const int CodeAlignment = 4; // Bytes. private const int CacheSize = 2047 * 1024 * 1024; diff --git a/src/Ryujinx.Tests.Memory/Tests.cs b/src/Ryujinx.Tests.Memory/Tests.cs index d8a243e3e..5ab01d5a5 100644 --- a/src/Ryujinx.Tests.Memory/Tests.cs +++ b/src/Ryujinx.Tests.Memory/Tests.cs @@ -7,7 +7,7 @@ namespace Ryujinx.Tests.Memory { public class Tests { - private const ulong MemorySize = 0x8000; + private static readonly ulong MemorySize = MemoryBlock.GetPageSize() * 8; private MemoryBlock _memoryBlock; @@ -44,14 +44,17 @@ namespace Ryujinx.Tests.Memory [Platform(Exclude = "MacOsX")] public void Test_Alias() { - using MemoryBlock backing = new MemoryBlock(0x10000, MemoryAllocationFlags.Mirrorable); - using MemoryBlock toAlias = new MemoryBlock(0x10000, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible); + ulong pageSize = MemoryBlock.GetPageSize(); + ulong blockSize = MemoryBlock.GetPageSize() * 16; - toAlias.MapView(backing, 0x1000, 0, 0x4000); - toAlias.UnmapView(backing, 0x3000, 0x1000); + using MemoryBlock backing = new MemoryBlock(blockSize, MemoryAllocationFlags.Mirrorable); + using MemoryBlock toAlias = new MemoryBlock(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible); + + toAlias.MapView(backing, pageSize, 0, pageSize * 4); + toAlias.UnmapView(backing, pageSize * 3, pageSize); toAlias.Write(0, 0xbadc0de); - Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, 0x1000), 0xbadc0de); + Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (int)pageSize), 0xbadc0de); } [Test] @@ -59,8 +62,12 @@ namespace Ryujinx.Tests.Memory [Platform(Exclude = "MacOsX")] public void Test_AliasRandom() { - using MemoryBlock backing = new MemoryBlock(0x80000, MemoryAllocationFlags.Mirrorable); - using MemoryBlock toAlias = new MemoryBlock(0x80000, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible); + ulong pageSize = MemoryBlock.GetPageSize(); + int pageBits = (int)ulong.Log2(pageSize); + ulong blockSize = MemoryBlock.GetPageSize() * 128; + + using MemoryBlock backing = new MemoryBlock(blockSize, MemoryAllocationFlags.Mirrorable); + using MemoryBlock toAlias = new MemoryBlock(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible); Random rng = new Random(123); @@ -72,16 +79,16 @@ namespace Ryujinx.Tests.Memory if ((rng.Next() & 1) != 0) { - toAlias.MapView(backing, (ulong)srcPage << 12, (ulong)dstPage << 12, (ulong)pages << 12); + toAlias.MapView(backing, (ulong)srcPage << pageBits, (ulong)dstPage << pageBits, (ulong)pages << pageBits); - int offset = rng.Next(0, 0x1000 - sizeof(int)); + int offset = rng.Next(0, (int)pageSize - sizeof(int)); - toAlias.Write((ulong)((dstPage << 12) + offset), 0xbadc0de); - Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (srcPage << 12) + offset), 0xbadc0de); + toAlias.Write((ulong)((dstPage << pageBits) + offset), 0xbadc0de); + Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (srcPage << pageBits) + offset), 0xbadc0de); } else { - toAlias.UnmapView(backing, (ulong)dstPage << 12, (ulong)pages << 12); + toAlias.UnmapView(backing, (ulong)dstPage << pageBits, (ulong)pages << pageBits); } } } @@ -91,7 +98,7 @@ namespace Ryujinx.Tests.Memory [Platform(Exclude = "MacOsX")] public void Test_AliasMapLeak() { - ulong pageSize = 4096; + ulong pageSize = MemoryBlock.GetPageSize(); ulong size = 100000 * pageSize; // The mappings limit on Linux is usually around 65K, so let's make sure we are above that. using MemoryBlock backing = new MemoryBlock(pageSize, MemoryAllocationFlags.Mirrorable); diff --git a/src/Ryujinx.Tests/Cpu/CpuTest.cs b/src/Ryujinx.Tests/Cpu/CpuTest.cs index 979b313b0..ad4ba539b 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTest.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTest.cs @@ -13,9 +13,9 @@ namespace Ryujinx.Tests.Cpu [TestFixture] public class CpuTest { - protected const ulong Size = 0x1000; - protected const ulong CodeBaseAddress = 0x1000; - protected const ulong DataBaseAddress = CodeBaseAddress + Size; + protected static readonly ulong Size = MemoryBlock.GetPageSize(); + protected static ulong CodeBaseAddress = Size; + protected static ulong DataBaseAddress = CodeBaseAddress + Size; private static bool Ignore_FpcrFz = false; private static bool Ignore_FpcrDn = false; @@ -39,12 +39,24 @@ namespace Ryujinx.Tests.Cpu [SetUp] public void Setup() { - _currAddress = CodeBaseAddress; + int pageBits = (int)ulong.Log2(Size); _ram = new MemoryBlock(Size * 2); - _memory = new MemoryManager(_ram, 1ul << 16); + _memory = new MemoryManager(_ram, 1ul << (pageBits + 4)); _memory.IncrementReferenceCount(); - _memory.Map(CodeBaseAddress, 0, Size * 2, MemoryMapFlags.Private); + + // Some tests depends on hardcoded address that were computed for 4KiB. + // We change the layout on non 4KiB platforms to keep compat here. + if (Size > 0x1000) + { + DataBaseAddress = 0; + CodeBaseAddress = Size; + } + + _currAddress = CodeBaseAddress; + + _memory.Map(CodeBaseAddress, 0, Size, MemoryMapFlags.Private); + _memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private); _context = CpuContext.CreateExecutionContext(); Translator.IsReadyForTranslation.Set(); diff --git a/src/Ryujinx.Tests/Cpu/CpuTest32.cs b/src/Ryujinx.Tests/Cpu/CpuTest32.cs index 47dc9f8a8..a1f6431cf 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTest32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTest32.cs @@ -13,9 +13,9 @@ namespace Ryujinx.Tests.Cpu [TestFixture] public class CpuTest32 { - protected const uint Size = 0x1000; - protected const uint CodeBaseAddress = 0x1000; - protected const uint DataBaseAddress = CodeBaseAddress + Size; + protected static readonly uint Size = (uint)MemoryBlock.GetPageSize(); + protected static uint CodeBaseAddress = Size; + protected static uint DataBaseAddress = CodeBaseAddress + Size; private uint _currAddress; @@ -33,12 +33,24 @@ namespace Ryujinx.Tests.Cpu [SetUp] public void Setup() { - _currAddress = CodeBaseAddress; + int pageBits = (int)ulong.Log2(Size); _ram = new MemoryBlock(Size * 2); - _memory = new MemoryManager(_ram, 1ul << 16); + _memory = new MemoryManager(_ram, 1ul << (pageBits + 4)); _memory.IncrementReferenceCount(); - _memory.Map(CodeBaseAddress, 0, Size * 2, MemoryMapFlags.Private); + + // Some tests depends on hardcoded address that were computed for 4KiB. + // We change the layout on non 4KiB platforms to keep compat here. + if (Size > 0x1000) + { + DataBaseAddress = 0; + CodeBaseAddress = Size; + } + + _currAddress = CodeBaseAddress; + + _memory.Map(CodeBaseAddress, 0, Size, MemoryMapFlags.Private); + _memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private); _context = CpuContext.CreateExecutionContext(); _context.IsAarch32 = true; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs index 2f9504cbf..c88c02c1b 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs @@ -1,6 +1,7 @@ #define SimdMemory32 using ARMeilleure.State; +using Ryujinx.Memory; using NUnit.Framework; using System; @@ -9,6 +10,7 @@ namespace Ryujinx.Tests.Cpu [Category("SimdMemory32")] public sealed class CpuTestSimdMemory32 : CpuTest32 { + private static readonly uint TestOffset = DataBaseAddress + 0x500; #if SimdMemory32 private uint[] _ldStModes = @@ -42,7 +44,7 @@ namespace Ryujinx.Tests.Cpu [Range(0u, 3u)] uint n, [Values(0x0u)] uint offset) { - var data = GenerateVectorSequence(0x1000); + var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize()); SetWorkingMemory(0, data); uint opcode = 0xf4a00000u; // VLD1.8 {D0[0]}, [R0], R0 @@ -58,7 +60,7 @@ namespace Ryujinx.Tests.Cpu opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc. - SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500); + SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset); CompareAgainstUnicorn(); } @@ -72,7 +74,7 @@ namespace Ryujinx.Tests.Cpu [Values] bool t, [Values(0x0u)] uint offset) { - var data = GenerateVectorSequence(0x1000); + var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize()); SetWorkingMemory(0, data); uint opcode = 0xf4a00c00u; // VLD1.8 {D0[0]}, [R0], R0 @@ -85,7 +87,7 @@ namespace Ryujinx.Tests.Cpu opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc. if (t) opcode |= 1 << 5; - SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500); + SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset); CompareAgainstUnicorn(); } @@ -98,7 +100,7 @@ namespace Ryujinx.Tests.Cpu [Range(0u, 10u)] uint mode, [Values(0x0u)] uint offset) { - var data = GenerateVectorSequence(0x1000); + var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize()); SetWorkingMemory(0, data); uint opcode = 0xf4200000u; // VLD4.8 {D0, D1, D2, D3}, [R0], R0 @@ -114,7 +116,7 @@ namespace Ryujinx.Tests.Cpu opcode |= ((vd & 0x10) << 18); opcode |= ((vd & 0xf) << 12); - SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500); + SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset); CompareAgainstUnicorn(); } @@ -128,7 +130,7 @@ namespace Ryujinx.Tests.Cpu [Range(0u, 3u)] uint n, [Values(0x0u)] uint offset) { - var data = GenerateVectorSequence(0x1000); + var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize()); SetWorkingMemory(0, data); (V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors(); @@ -146,7 +148,7 @@ namespace Ryujinx.Tests.Cpu opcode |= (n & 3) << 8; // ST1 is 0, ST2 is 1 etc. - SingleOpcode(opcode, r0: 0x2500, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: 0x2500); + SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset); CompareAgainstUnicorn(); } @@ -159,7 +161,7 @@ namespace Ryujinx.Tests.Cpu [Range(0u, 10u)] uint mode, [Values(0x0u)] uint offset) { - var data = GenerateVectorSequence(0x1000); + var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize()); SetWorkingMemory(0, data); (V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors(); @@ -177,7 +179,7 @@ namespace Ryujinx.Tests.Cpu opcode |= ((vd & 0x10) << 18); opcode |= ((vd & 0xf) << 12); - SingleOpcode(opcode, r0: 0x2500, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: 0x2500); + SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset); CompareAgainstUnicorn(); } @@ -189,7 +191,7 @@ namespace Ryujinx.Tests.Cpu [Values(0x1u, 0x32u)] uint regs, [Values] bool single) { - var data = GenerateVectorSequence(0x1000); + var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize()); SetWorkingMemory(0, data); uint opcode = 0xec100a00u; // VST4.8 {D0, D1, D2, D3}, [R0], R0 @@ -225,7 +227,7 @@ namespace Ryujinx.Tests.Cpu opcode |= regs & 0xff; - SingleOpcode(opcode, r0: 0x2500, sp: 0x2500); + SingleOpcode(opcode, r0: TestOffset, sp: TestOffset); CompareAgainstUnicorn(); } @@ -237,7 +239,7 @@ namespace Ryujinx.Tests.Cpu [Values(0x0u)] uint imm, [Values] bool sub) { - var data = GenerateVectorSequence(0x1000); + var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize()); SetWorkingMemory(0, data); uint opcode = 0xed900a00u; // VLDR.32 S0, [R0, #0] @@ -260,7 +262,7 @@ namespace Ryujinx.Tests.Cpu } opcode |= imm & 0xff; - SingleOpcode(opcode, r0: 0x2500); + SingleOpcode(opcode, r0: TestOffset); CompareAgainstUnicorn(); } @@ -272,7 +274,7 @@ namespace Ryujinx.Tests.Cpu [Values(0x0u)] uint imm, [Values] bool sub) { - var data = GenerateVectorSequence(0x1000); + var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize()); SetWorkingMemory(0, data); uint opcode = 0xed800a00u; // VSTR.32 S0, [R0, #0] @@ -297,7 +299,7 @@ namespace Ryujinx.Tests.Cpu (V128 vec1, V128 vec2, _, _) = GenerateTestVectors(); - SingleOpcode(opcode, r0: 0x2500, v0: vec1, v1: vec2); + SingleOpcode(opcode, r0: TestOffset, v0: vec1, v1: vec2); CompareAgainstUnicorn(); } diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs index b19137a4b..603e2a559 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs @@ -3,6 +3,7 @@ using ARMeilleure.State; using NUnit.Framework; using System.Collections.Generic; +using System.Runtime.InteropServices; namespace Ryujinx.Tests.Cpu { @@ -703,6 +704,11 @@ namespace Ryujinx.Tests.Cpu [Values] bool q, [Values] bool u) { + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + Assert.Ignore("Unicorn on ARM64 crash while executing this test"); + } + uint opcode = 0xf2000400u; // VSHL.S8 D0, D0, D0 if (q) { diff --git a/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs b/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs index 2c83b01d8..03d90a1f1 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs @@ -109,7 +109,7 @@ namespace Ryujinx.Tests.Cpu ExecuteOpcodes(runUnicorn: false); - Assert.That(GetContext().GetX(0), Is.EqualTo(0x1005)); + Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x5)); } [Test] @@ -133,7 +133,7 @@ namespace Ryujinx.Tests.Cpu ExecuteOpcodes(runUnicorn: false); - Assert.That(GetContext().GetX(0), Is.EqualTo(0x1005)); + Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x5)); Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false)); } @@ -160,7 +160,7 @@ namespace Ryujinx.Tests.Cpu ExecuteOpcodes(runUnicorn: false); - Assert.That(GetContext().GetX(0), Is.EqualTo(0x1007)); + Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x7)); Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false)); } } diff --git a/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs b/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs index b740f524a..3d13ff733 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs @@ -268,6 +268,12 @@ namespace Ryujinx.Tests.Cpu [Test] public void TestRandomTestCases([ValueSource(nameof(RandomTestCases))] PrecomputedThumbTestCase test) { + if (Size != 0x1000) + { + // TODO: Change it to depend on DataBaseAddress instead. + Assert.Ignore("This test currently only support 4KiB page size"); + } + RunPrecomputedTestCase(test); }