From 6bc080b52ca9c6050ba7901ca5e36c287c879c8d Mon Sep 17 00:00:00 2001 From: _Neo_ Date: Tue, 12 May 2026 19:02:58 +0300 Subject: [PATCH] More tests + disable all builds except macOS --- .forgejo/workflows/build.yml | 195 ++++++------- .../AppleHv/HvExecutionContextVcpu.cs | 266 ++++++++++-------- 2 files changed, 236 insertions(+), 225 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index e7052a6f6..361379051 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -27,117 +27,94 @@ jobs: matrix: configuration: [Release] platform: - - { name: win-x64, zip_os_name: win_x64 } - #- { name: win-arm64, zip_os_name: win_arm64 } - - { name: linux-x64, zip_os_name: linux_x64 } - - { name: linux-arm64, zip_os_name: linux_arm64 } - #- { name: osx-x64, zip_os_name: osx_x64 } - + # - { name: win-x64, zip_os_name: win_x64 } + # - { name: win-arm64, zip_os_name: win_arm64 } + # - { name: linux-x64, zip_os_name: linux_x64 } + # - { name: linux-arm64, zip_os_name: linux_arm64 } + # - { name: osx-x64, zip_os_name: osx_x64 } fail-fast: false - steps: - - uses: actions/checkout@v6 - - uses: actions/setup-dotnet@v5 - with: - global-json-file: global.json - - - name: Install GLI - uses: actions/setup-gli@v1 - with: - token: ${{ secrets.SETUP_GLI_TOKEN }} - - - name: Install 7zip - run: | - sudo apt update && sudo apt install -y 7zip - - - name: Overwrite csc problem matcher - run: echo "::add-matcher::.forgejo/csc.json" - - - name: Get version info - id: version_info - run: | - echo "result=$(gli get-next-version -c Canary -R)" >> $FORGEJO_OUTPUT - echo "git_short_hash=$(git rev-parse --short "${{ forgejo.sha }}")" >> $FORGEJO_OUTPUT - shell: bash - - - name: Change config filename - run: sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs - shell: bash - if: forgejo.event_name == 'pull_request' - - - name: 'Cache: ~/.nuget/packages' - uses: actions/cache@v5 - with: - path: | - ~/.nuget/packages - key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }} - - - name: Build - run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ steps.version_info.outputs.result }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:ExtraDefineConstants=DISABLE_UPDATER - - - name: Test - uses: actions/unstable-commands@v1 - with: - commands: dotnet test --no-build -c "${{ matrix.configuration }}" - timeout-minutes: 10 - retry-codes: 139 - if: matrix.platform.name != 'linux-arm64' - - - name: Publish Ryujinx - run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.result }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained - if: forgejo.event_name == 'pull_request' - - - name: Packing Windows builds - if: contains(matrix.platform.name, 'win') - run: | - 7z a artifact/ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-${{ matrix.platform.zip_os_name }}.7z publish - shell: bash - - - name: Upload Ryujinx Windows artifact - uses: actions/upload-artifact@v5 - with: - name: ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-${{ matrix.platform.zip_os_name }} - path: artifact - if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'win') - - - name: Build AppImage - if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'linux') - run: | - chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh - - PLATFORM_NAME="${{ matrix.platform.name }}" - - sudo apt update && sudo apt install -y zsync desktop-file-utils appstream libfuse2t64 - - mkdir -p tools - export PATH="$PATH:$(readlink -f tools)" - - # Setup appimagetool - wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage" - chmod +x tools/appimagetool - chmod +x distribution/linux/appimage/build-appimage.sh - - # Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name) - if [ "$PLATFORM_NAME" = "linux-x64" ]; then - ARCH_NAME=x64 - export ARCH=x86_64 - elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then - ARCH_NAME=arm64 - export ARCH=aarch64 - else - echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME"" - exit 1 - fi - - BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh - shell: bash - - - name: Upload Ryujinx AppImage artifact - uses: actions/upload-artifact@v5 - if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'linux') - with: - name: ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-${{ matrix.platform.zip_os_name }}-AppImage - path: publish_appimage + # steps: + # - uses: actions/checkout@v6 + # - uses: actions/setup-dotnet@v5 + # with: + # global-json-file: global.json + # - name: Install GLI + # uses: actions/setup-gli@v1 + # with: + # token: ${{ secrets.SETUP_GLI_TOKEN }} + # - name: Install 7zip + # run: | + # sudo apt update && sudo apt install -y 7zip + # - name: Overwrite csc problem matcher + # run: echo "::add-matcher::.forgejo/csc.json" + # - name: Get version info + # id: version_info + # run: | + # echo "result=$(gli get-next-version -c Canary -R)" >> $FORGEJO_OUTPUT + # echo "git_short_hash=$(git rev-parse --short "${{ forgejo.sha }}")" >> $FORGEJO_OUTPUT + # shell: bash + # - name: Change config filename + # run: sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/PRConfig\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs + # shell: bash + # if: forgejo.event_name == 'pull_request' + # - name: 'Cache: ~/.nuget/packages' + # uses: actions/cache@v5 + # with: + # path: ~/.nuget/packages + # key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }} + # - name: Build + # run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ steps.version_info.outputs.result }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:ExtraDefineConstants=DISABLE_UPDATER + # - name: Test + # uses: actions/unstable-commands@v1 + # with: + # commands: dotnet test --no-build -c "${{ matrix.configuration }}" + # timeout-minutes: 10 + # retry-codes: 139 + # if: matrix.platform.name != 'linux-arm64' + # - name: Publish Ryujinx + # run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.result }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained + # if: forgejo.event_name == 'pull_request' + # - name: Packing Windows builds + # if: contains(matrix.platform.name, 'win') + # run: | + # 7z a artifact/ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-${{ matrix.platform.zip_os_name }}.7z publish + # shell: bash + # - name: Upload Ryujinx Windows artifact + # uses: actions/upload-artifact@v5 + # with: + # name: ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-${{ matrix.platform.zip_os_name }} + # path: artifact + # if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'win') + # - name: Build AppImage + # if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'linux') + # run: | + # chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh + # PLATFORM_NAME="${{ matrix.platform.name }}" + # sudo apt update && sudo apt install -y zsync desktop-file-utils appstream libfuse2t64 + # mkdir -p tools + # export PATH="$PATH:$(readlink -f tools)" + # wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage" + # chmod +x tools/appimagetool + # chmod +x distribution/linux/appimage/build-appimage.sh + # if [ "$PLATFORM_NAME" = "linux-x64" ]; then + # ARCH_NAME=x64 + # export ARCH=x86_64 + # elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then + # ARCH_NAME=arm64 + # export ARCH=aarch64 + # else + # echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME"" + # exit 1 + # fi + # BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh + # shell: bash + # - name: Upload Ryujinx AppImage artifact + # uses: actions/upload-artifact@v5 + # if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'linux') + # with: + # name: ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-${{ matrix.platform.zip_os_name }}-AppImage + # path: publish_appimage build_macos: name: macOS Universal (${{ matrix.configuration }}) diff --git a/src/Ryujinx.Cpu/AppleHv/HvExecutionContextVcpu.cs b/src/Ryujinx.Cpu/AppleHv/HvExecutionContextVcpu.cs index 36be2e250..2ca4d84c5 100644 --- a/src/Ryujinx.Cpu/AppleHv/HvExecutionContextVcpu.cs +++ b/src/Ryujinx.Cpu/AppleHv/HvExecutionContextVcpu.cs @@ -34,110 +34,6 @@ namespace Ryujinx.Cpu.AppleHv } } - public ulong Pc - { - get - { - HvApi.hv_vcpu_get_reg(_vcpu, HvReg.PC, out ulong pc).ThrowOnError(); - return pc; - } - set - { - HvApi.hv_vcpu_set_reg(_vcpu, HvReg.PC, value).ThrowOnError(); - } - } - - public ulong ElrEl1 - { - get - { - HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ELR_EL1, out ulong elr).ThrowOnError(); - return elr; - } - set - { - HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ELR_EL1, value).ThrowOnError(); - } - } - - public ulong EsrEl1 - { - get - { - HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ESR_EL1, out ulong esr).ThrowOnError(); - return esr; - } - set - { - HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ESR_EL1, value).ThrowOnError(); - } - } - - public long TpidrEl0 - { - get - { - HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, out ulong tpidrEl0).ThrowOnError(); - return (long)tpidrEl0; - } - set - { - HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, (ulong)value).ThrowOnError(); - } - } - - public long TpidrroEl0 - { - get - { - HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, out ulong tpidrroEl0).ThrowOnError(); - return (long)tpidrroEl0; - } - set - { - HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, (ulong)value).ThrowOnError(); - } - } - - public uint Pstate - { - get - { - HvApi.hv_vcpu_get_reg(_vcpu, HvReg.CPSR, out ulong cpsr).ThrowOnError(); - return (uint)cpsr; - } - set - { - HvApi.hv_vcpu_set_reg(_vcpu, HvReg.CPSR, (ulong)value).ThrowOnError(); - } - } - - public uint Fpcr - { - get - { - HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPCR, out ulong fpcr).ThrowOnError(); - return (uint)fpcr; - } - set - { - HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPCR, (ulong)value).ThrowOnError(); - } - } - - public uint Fpsr - { - get - { - HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPSR, out ulong fpsr).ThrowOnError(); - return (uint)fpsr; - } - set - { - HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPSR, (ulong)value).ThrowOnError(); - } - } - private readonly ulong _vcpu; private int _interruptRequested; @@ -146,19 +42,163 @@ namespace Ryujinx.Cpu.AppleHv _vcpu = vcpu; } + public ulong Pc + { + get + { + var result = HvApi.hv_vcpu_get_reg(_vcpu, HvReg.PC, out ulong pc); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on PC"); return 0; } + result.ThrowOnError(); + return pc; + } + set + { + var result = HvApi.hv_vcpu_set_reg(_vcpu, HvReg.PC, value); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on PC (set)"); return; } + result.ThrowOnError(); + } + } + + public ulong ElrEl1 + { + get + { + var result = HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ELR_EL1, out ulong elr); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on ELR_EL1"); return 0; } + result.ThrowOnError(); + return elr; + } + set + { + var result = HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ELR_EL1, value); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on ELR_EL1 (set)"); return; } + result.ThrowOnError(); + } + } + + public ulong EsrEl1 + { + get + { + var result = HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ESR_EL1, out ulong esr); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on ESR_EL1"); return 0; } + result.ThrowOnError(); + return esr; + } + set + { + var result = HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ESR_EL1, value); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on ESR_EL1 (set)"); return; } + result.ThrowOnError(); + } + } + + public long TpidrEl0 + { + get + { + var result = HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, out ulong val); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on TPIDR_EL0"); return 0; } + result.ThrowOnError(); + return (long)val; + } + set + { + var result = HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, (ulong)value); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on TPIDR_EL0 (set)"); return; } + result.ThrowOnError(); + } + } + + public long TpidrroEl0 + { + get + { + var result = HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, out ulong val); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on TPIDRRO_EL0"); return 0; } + result.ThrowOnError(); + return (long)val; + } + set + { + var result = HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, (ulong)value); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on TPIDRRO_EL0 (set)"); return; } + result.ThrowOnError(); + } + } + + public uint Pstate + { + get + { + var result = HvApi.hv_vcpu_get_reg(_vcpu, HvReg.CPSR, out ulong cpsr); + if (result == HvResult.BadArgument) + { + Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on CPSR (Pstate) - common during early GetThreadContext3"); + return 0; + } + result.ThrowOnError(); + return (uint)cpsr; + } + set + { + var result = HvApi.hv_vcpu_set_reg(_vcpu, HvReg.CPSR, (ulong)value); + if (result == HvResult.BadArgument) + { + Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on CPSR (set)"); + return; + } + result.ThrowOnError(); + } + } + + public uint Fpcr + { + get + { + var result = HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPCR, out ulong val); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on FPCR"); return 0; } + result.ThrowOnError(); + return (uint)val; + } + set + { + var result = HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPCR, (ulong)value); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on FPCR (set)"); return; } + result.ThrowOnError(); + } + } + + public uint Fpsr + { + get + { + var result = HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPSR, out ulong val); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on FPSR"); return 0; } + result.ThrowOnError(); + return (uint)val; + } + set + { + var result = HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPSR, (ulong)value); + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on FPSR (set)"); return; } + result.ThrowOnError(); + } + } + public ulong GetX(int index) { if (index == 31) { var result = HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.SP_EL0, out ulong value); - if (result == HvResult.BadArgument) return 0; + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on SP_EL0 (X31)"); return 0; } result.ThrowOnError(); return value; } else if (index >= 0 && index <= 30) { var result = HvApi.hv_vcpu_get_reg(_vcpu, HvReg.X0 + (uint)index, out ulong value); - if (result == HvResult.BadArgument) return 0; + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, $"HV_BAD_ARGUMENT on X{index}"); return 0; } result.ThrowOnError(); return value; } @@ -170,13 +210,13 @@ namespace Ryujinx.Cpu.AppleHv if (index == 31) { var result = HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.SP_EL0, value); - if (result == HvResult.BadArgument) return; + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, "HV_BAD_ARGUMENT on SP_EL0 (set)"); return; } result.ThrowOnError(); } else if (index >= 0 && index <= 30) { var result = HvApi.hv_vcpu_set_reg(_vcpu, HvReg.X0 + (uint)index, value); - if (result == HvResult.BadArgument) return; + if (result == HvResult.BadArgument) { Logger.Warning?.Print(LogClass.Cpu, $"HV_BAD_ARGUMENT on X{index} (set)"); return; } result.ThrowOnError(); } } @@ -184,19 +224,16 @@ namespace Ryujinx.Cpu.AppleHv public V128 GetV(int index) { if (index < 0 || index > 31) - { return V128.Zero; - } var result = HvApi.hv_vcpu_get_simd_fp_reg(_vcpu, HvSimdFPReg.Q0 + (uint)index, out HvSimdFPUchar16 value); if (result == HvResult.BadArgument) { + Logger.Warning?.Print(LogClass.Cpu, $"HV_BAD_ARGUMENT on V{index} (SIMD)"); return V128.Zero; } if (result != HvResult.Success) - { result.ThrowOnError(); - } return new V128(value.Low, value.High); } @@ -204,19 +241,16 @@ namespace Ryujinx.Cpu.AppleHv public void SetV(int index, V128 value) { if (index < 0 || index > 31) - { return; - } var result = _setSimdFpReg(_vcpu, HvSimdFPReg.Q0 + (uint)index, value, _setSimdFpRegNativePtr); if (result == HvResult.BadArgument) { + Logger.Warning?.Print(LogClass.Cpu, $"HV_BAD_ARGUMENT on V{index} (SIMD set)"); return; } if (result != HvResult.Success) - { result.ThrowOnError(); - } } public void RequestInterrupt()