Fix system register state handling

We failed to preserve NCSZ, and and we stored instead of loaded FPCR when returning to guest.
This commit is contained in:
Billy Laws 2023-04-05 15:03:00 +01:00
parent 77ca290a78
commit e0c487f607
3 changed files with 19 additions and 10 deletions

View File

@ -141,6 +141,7 @@ namespace skyline::kernel::type {
"MOV X29, XZR\n\t" "MOV X29, XZR\n\t"
"MSR FPSR, XZR\n\t" "MSR FPSR, XZR\n\t"
"MSR FPCR, XZR\n\t" "MSR FPCR, XZR\n\t"
"MSR NZCV, XZR\n\t"
"DUP V0.16B, WZR\n\t" "DUP V0.16B, WZR\n\t"
"DUP V1.16B, WZR\n\t" "DUP V1.16B, WZR\n\t"
"DUP V2.16B, WZR\n\t" "DUP V2.16B, WZR\n\t"

View File

@ -38,11 +38,16 @@ SaveCtx:
STP Q28, Q29, [LR, #(0xA0 + 16 * 28)] STP Q28, Q29, [LR, #(0xA0 + 16 * 28)]
STP Q30, Q31, [LR, #(0xA0 + 16 * 30)] STP Q30, Q31, [LR, #(0xA0 + 16 * 30)]
/* Store FPCR/FPSR */
/* Store System Registers */
STR X0, [SP, #-16]!
MRS X0, FPSR MRS X0, FPSR
STR W0, [LR, #0x298] STR W0, [LR, #0x298]
MRS X1, FPCR MRS X0, FPCR
STR W1, [LR, #0x29C] STR W0, [LR, #0x29C]
MRS X0, NZCV
STR W0, [LR, #0x2C0]
LDR X0, [SP], #16
/* Restore Scratch Register */ /* Restore Scratch Register */
LDR LR, [SP, #8] LDR LR, [SP, #8]
@ -72,11 +77,13 @@ LoadCtx:
LDP Q28, Q29, [LR, #(0xA0 + 16 * 28)] LDP Q28, Q29, [LR, #(0xA0 + 16 * 28)]
LDP Q30, Q31, [LR, #(0xA0 + 16 * 30)] LDP Q30, Q31, [LR, #(0xA0 + 16 * 30)]
/* Store FPCR/FPSR */ /* Load System Registers */
MRS X0, FPSR LDR W0, [LR, #0x298]
STR W0, [LR, #0x298] MSR FPSR, X0
MRS X1, FPCR LDR W0, [LR, #0x29C]
STR W1, [LR, #0x29C] MSR FPCR, X0
LDR W0, [LR, #0x2C0]
MSR NZCV, X0
/* Load GP Registers */ /* Load GP Registers */
LDP X0, X1, [LR, #(8 * 0)] LDP X0, X1, [LR, #(8 * 0)]

View File

@ -98,13 +98,14 @@ namespace skyline {
u8 *hostSp; //!< Host Stack Pointer, same as above u8 *hostSp; //!< Host Stack Pointer, same as above
u8 *tpidrroEl0; //!< Emulated HOS TPIDRRO_EL0 u8 *tpidrroEl0; //!< Emulated HOS TPIDRRO_EL0
u8 *tpidrEl0; //!< Emulated HOS TPIDR_EL0 u8 *tpidrEl0; //!< Emulated HOS TPIDR_EL0
u32 nzcv;
const DeviceState *state; const DeviceState *state;
u64 magic{constant::SkyTlsMagic}; u64 magic{constant::SkyTlsMagic};
}; };
namespace guest { namespace guest {
constexpr size_t SaveCtxSize{34}; //!< The size of the SaveCtx function in 32-bit ARMv8 instructions constexpr size_t SaveCtxSize{38}; //!< The size of the SaveCtx function in 32-bit ARMv8 instructions
constexpr size_t LoadCtxSize{34}; //!< The size of the LoadCtx function in 32-bit ARMv8 instructions constexpr size_t LoadCtxSize{36}; //!< The size of the LoadCtx function in 32-bit ARMv8 instructions
/** /**
* @brief Saves the context from CPU registers into TLS * @brief Saves the context from CPU registers into TLS