mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 18:11:51 +01:00
Skip Saving Callee-Saved Registers + Fix GetMemoryObject
This commit is contained in:
parent
31efb5e930
commit
cffbfc8034
@ -4,8 +4,6 @@
|
|||||||
#include <android/sharedmem.h>
|
#include <android/sharedmem.h>
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <os.h>
|
|
||||||
#include <nce.h>
|
|
||||||
#include "KPrivateMemory.h"
|
#include "KPrivateMemory.h"
|
||||||
#include "KProcess.h"
|
#include "KProcess.h"
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ namespace skyline::kernel::type {
|
|||||||
void KProcess::InitializeHeap() {
|
void KProcess::InitializeHeap() {
|
||||||
constexpr size_t DefaultHeapSize{0x200000};
|
constexpr size_t DefaultHeapSize{0x200000};
|
||||||
heap = heap.make_shared(state, reinterpret_cast<u8 *>(state.process->memory.heap.address), DefaultHeapSize, memory::Permission{true, true, false}, memory::states::Heap);
|
heap = heap.make_shared(state, reinterpret_cast<u8 *>(state.process->memory.heap.address), DefaultHeapSize, memory::Permission{true, true, false}, memory::states::Heap);
|
||||||
|
InsertItem(heap); // Insert it into the handle table so GetMemoryObject will contain it
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *KProcess::AllocateTlsSlot() {
|
u8 *KProcess::AllocateTlsSlot() {
|
||||||
@ -59,6 +60,7 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
for (KHandle index{}; index < handles.size(); index++) {
|
for (KHandle index{}; index < handles.size(); index++) {
|
||||||
auto &object{handles[index]};
|
auto &object{handles[index]};
|
||||||
|
if (object) {
|
||||||
switch (object->objectType) {
|
switch (object->objectType) {
|
||||||
case type::KType::KPrivateMemory:
|
case type::KType::KPrivateMemory:
|
||||||
case type::KType::KSharedMemory:
|
case type::KType::KSharedMemory:
|
||||||
@ -72,6 +74,7 @@ namespace skyline::kernel::type {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
#include <android/sharedmem.h>
|
#include <android/sharedmem.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
#include <os.h>
|
|
||||||
#include <nce.h>
|
|
||||||
#include "KSharedMemory.h"
|
#include "KSharedMemory.h"
|
||||||
#include "KProcess.h"
|
#include "KProcess.h"
|
||||||
|
|
||||||
|
@ -38,9 +38,9 @@ namespace skyline::kernel::type {
|
|||||||
asm volatile(
|
asm volatile(
|
||||||
"MRS X0, TPIDR_EL0\n\t"
|
"MRS X0, TPIDR_EL0\n\t"
|
||||||
"MSR TPIDR_EL0, %x0\n\t" // Set TLS to ThreadContext
|
"MSR TPIDR_EL0, %x0\n\t" // Set TLS to ThreadContext
|
||||||
"STR X0, [%x0, #0x2F0]\n\t" // Write ThreadContext::hostTpidrEl0
|
"STR X0, [%x0, #0x2A0]\n\t" // Write ThreadContext::hostTpidrEl0
|
||||||
"MOV X0, SP\n\t"
|
"MOV X0, SP\n\t"
|
||||||
"STR X0, [%x0, #0x2F8]\n\t" // Write ThreadContext::hostSp
|
"STR X0, [%x0, #0x2A8]\n\t" // Write ThreadContext::hostSp
|
||||||
"MOV SP, %x1\n\t" // Replace SP with guest stack
|
"MOV SP, %x1\n\t" // Replace SP with guest stack
|
||||||
"MOV LR, %x2\n\t" // Store entry in Link Register so it is jumped to on return
|
"MOV LR, %x2\n\t" // Store entry in Link Register so it is jumped to on return
|
||||||
"MOV X0, %x3\n\t" // Store the argument in X0
|
"MOV X0, %x3\n\t" // Store the argument in X0
|
||||||
|
@ -28,9 +28,8 @@ namespace skyline::nce {
|
|||||||
throw exception("Unimplemented SVC 0x{:X}", svc);
|
throw exception("Unimplemented SVC 0x{:X}", svc);
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
throw exception("{} (SVC: 0x{:X})", e.what(), svc);
|
state.logger->Error("{} (SVC: 0x{:X})", e.what(), svc);
|
||||||
// Jumps off the edge?
|
exit(0);
|
||||||
// Look into this
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,12 +119,12 @@ namespace skyline::nce {
|
|||||||
|
|
||||||
/* Replace Skyline TLS with host TLS */
|
/* Replace Skyline TLS with host TLS */
|
||||||
patch[index++] = 0xD53BD041; // MRS X1, TPIDR_EL0
|
patch[index++] = 0xD53BD041; // MRS X1, TPIDR_EL0
|
||||||
patch[index++] = 0xF9417822; // LDR X2, [X1, #0x2F0] (ThreadContext::hostTpidrEl0)
|
patch[index++] = 0xF9415022; // LDR X2, [X1, #0x2A0] (ThreadContext::hostTpidrEl0)
|
||||||
|
|
||||||
/* Replace guest stack with host stack */
|
/* Replace guest stack with host stack */
|
||||||
patch[index++] = 0xD51BD042; // MSR TPIDR_EL0, X2
|
patch[index++] = 0xD51BD042; // MSR TPIDR_EL0, X2
|
||||||
patch[index++] = 0x910003E2; // MOV X2, SP
|
patch[index++] = 0x910003E2; // MOV X2, SP
|
||||||
patch[index++] = 0xF9417C23; // LDR X3, [X1, #0x2F8] (ThreadContext::hostSp)
|
patch[index++] = 0xF9415423; // LDR X3, [X1, #0x2A8] (ThreadContext::hostSp)
|
||||||
patch[index++] = 0x9100007F; // MOV SP, X3
|
patch[index++] = 0x9100007F; // MOV SP, X3
|
||||||
|
|
||||||
/* Store Skyline TLS + guest SP on stack */
|
/* Store Skyline TLS + guest SP on stack */
|
||||||
@ -199,9 +198,9 @@ namespace skyline::nce {
|
|||||||
/* Retrieve emulated TLS register from ThreadContext */
|
/* Retrieve emulated TLS register from ThreadContext */
|
||||||
patch[index++] = 0xD53BD040; // MRS X0, TPIDR_EL0
|
patch[index++] = 0xD53BD040; // MRS X0, TPIDR_EL0
|
||||||
if (mrs.srcReg == TpidrroEl0)
|
if (mrs.srcReg == TpidrroEl0)
|
||||||
patch[index++] = 0xF9418000; // LDR X0, [X0, #0x300] (ThreadContext::tpidrroEl0)
|
patch[index++] = 0xF9415800; // LDR X0, [X0, #0x2B0] (ThreadContext::tpidrroEl0)
|
||||||
else
|
else
|
||||||
patch[index++] = 0xF9418400; // LDR X0, [X0, #0x308] (ThreadContext::tpidrEl0)
|
patch[index++] = 0xF9415C00; // LDR X0, [X0, #0x2B8] (ThreadContext::tpidrEl0)
|
||||||
|
|
||||||
/* Restore Scratch Register and Return */
|
/* Restore Scratch Register and Return */
|
||||||
if (mrs.destReg != regs::X0) {
|
if (mrs.destReg != regs::X0) {
|
||||||
@ -266,7 +265,7 @@ namespace skyline::nce {
|
|||||||
/* Store new TLS value into ThreadContext */
|
/* Store new TLS value into ThreadContext */
|
||||||
patch[index++] = x0x1 ? 0xD53BD040 : 0xD53BD042; // MRS X(0/2), TPIDR_EL0
|
patch[index++] = x0x1 ? 0xD53BD040 : 0xD53BD042; // MRS X(0/2), TPIDR_EL0
|
||||||
patch[index++] = instr::Mov(x0x1 ? regs::X1 : regs::X3, regs::X(msr.srcReg)).raw;
|
patch[index++] = instr::Mov(x0x1 ? regs::X1 : regs::X3, regs::X(msr.srcReg)).raw;
|
||||||
patch[index++] = x0x1 ? 0xF9018401 : 0xF9018403; // STR X(1/3), [X0, #0x308] (ThreadContext::tpidrEl0)
|
patch[index++] = x0x1 ? 0xF9015C01 : 0xF9015C03; // STR X(1/3), [X0, #0x4B8] (ThreadContext::tpidrEl0)
|
||||||
|
|
||||||
/* Restore Scratch Registers and Return */
|
/* Restore Scratch Registers and Return */
|
||||||
patch[index++] = x0x1 ? 0xA8C107E0 : 0xA8C10FE2; // LDP X(0/2), X(1/3), [SP], #16
|
patch[index++] = x0x1 ? 0xA8C107E0 : 0xA8C10FE2; // LDP X(0/2), X(1/3), [SP], #16
|
||||||
|
@ -9,45 +9,40 @@ SaveCtx:
|
|||||||
MRS LR, TPIDR_EL0
|
MRS LR, TPIDR_EL0
|
||||||
|
|
||||||
/* Store GP Registers */
|
/* Store GP Registers */
|
||||||
STP X0, X1, [LR, #0]
|
STP X0, X1, [LR, #(8 * 0)]
|
||||||
STP X2, X3, [LR, #16]
|
STP X2, X3, [LR, #(8 * 2)]
|
||||||
STP X4, X5, [LR, #32]
|
STP X4, X5, [LR, #(8 * 4)]
|
||||||
STP X6, X7, [LR, #48]
|
STP X6, X7, [LR, #(8 * 6)]
|
||||||
STP X8, X9, [LR, #64]
|
STP X8, X9, [LR, #(8 * 8)]
|
||||||
STP X10, X11, [LR, #80]
|
STP X10, X11, [LR, #(8 * 10)]
|
||||||
STP X12, X13, [LR, #96]
|
STP X12, X13, [LR, #(8 * 12)]
|
||||||
STP X14, X15, [LR, #112]
|
STP X14, X15, [LR, #(8 * 14)]
|
||||||
STP X16, X17, [LR, #128]
|
STP X16, X17, [LR, #(8 * 16)]
|
||||||
STP X18, X19, [LR, #144]
|
STR X18, [LR, #(8 * 18)]
|
||||||
STP X20, X21, [LR, #160]
|
|
||||||
STP X22, X23, [LR, #176]
|
|
||||||
STP X24, X25, [LR, #192]
|
|
||||||
STP X26, X27, [LR, #208]
|
|
||||||
STP X28, X29, [LR, #224]
|
|
||||||
|
|
||||||
/* Store FP Registers */
|
/* Store FP Registers */
|
||||||
STP Q0, Q1, [LR, #240]
|
STP Q0, Q1, [LR, #(0xA0 + 16 * 0)]
|
||||||
STP Q2, Q3, [LR, #272]
|
STP Q2, Q3, [LR, #(0xA0 + 16 * 2)]
|
||||||
STP Q4, Q5, [LR, #304]
|
STP Q4, Q5, [LR, #(0xA0 + 16 * 4)]
|
||||||
STP Q6, Q7, [LR, #336]
|
STP Q6, Q7, [LR, #(0xA0 + 16 * 6)]
|
||||||
STP Q8, Q9, [LR, #368]
|
STP Q8, Q9, [LR, #(0xA0 + 16 * 8)]
|
||||||
STP Q10, Q11, [LR, #400]
|
STP Q10, Q11, [LR, #(0xA0 + 16 * 10)]
|
||||||
STP Q12, Q13, [LR, #432]
|
STP Q12, Q13, [LR, #(0xA0 + 16 * 12)]
|
||||||
STP Q14, Q15, [LR, #464]
|
STP Q14, Q15, [LR, #(0xA0 + 16 * 14)]
|
||||||
STP Q16, Q17, [LR, #496]
|
STP Q16, Q17, [LR, #(0xA0 + 16 * 16)]
|
||||||
STP Q18, Q19, [LR, #528]
|
STP Q18, Q19, [LR, #(0xA0 + 16 * 18)]
|
||||||
STP Q20, Q21, [LR, #560]
|
STP Q20, Q21, [LR, #(0xA0 + 16 * 20)]
|
||||||
STP Q22, Q23, [LR, #592]
|
STP Q22, Q23, [LR, #(0xA0 + 16 * 22)]
|
||||||
STP Q24, Q25, [LR, #624]
|
STP Q24, Q25, [LR, #(0xA0 + 16 * 24)]
|
||||||
STP Q26, Q27, [LR, #656]
|
STP Q26, Q27, [LR, #(0xA0 + 16 * 26)]
|
||||||
STP Q28, Q29, [LR, #688]
|
STP Q28, Q29, [LR, #(0xA0 + 16 * 28)]
|
||||||
STP Q30, Q31, [LR, #720]
|
STP Q30, Q31, [LR, #(0xA0 + 16 * 30)]
|
||||||
|
|
||||||
/* Store FPCR/FPSR */
|
/* Store FPCR/FPSR */
|
||||||
MRS X0, FPSR
|
MRS X0, FPSR
|
||||||
STR W0, [LR, #744]
|
STR W0, [LR, #0x298]
|
||||||
MRS X1, FPCR
|
MRS X1, FPCR
|
||||||
STR W1, [LR, #748]
|
STR W1, [LR, #0x29C]
|
||||||
|
|
||||||
/* Restore Scratch Register */
|
/* Restore Scratch Register */
|
||||||
LDR LR, [SP, #8]
|
LDR LR, [SP, #8]
|
||||||
@ -60,45 +55,40 @@ LoadCtx:
|
|||||||
MRS LR, TPIDR_EL0
|
MRS LR, TPIDR_EL0
|
||||||
|
|
||||||
/* Load FP Registers */
|
/* Load FP Registers */
|
||||||
LDP Q0, Q1, [LR, #240]
|
LDP Q0, Q1, [LR, #(0xA0 + 16 * 0)]
|
||||||
LDP Q2, Q3, [LR, #272]
|
LDP Q2, Q3, [LR, #(0xA0 + 16 * 2)]
|
||||||
LDP Q4, Q5, [LR, #304]
|
LDP Q4, Q5, [LR, #(0xA0 + 16 * 4)]
|
||||||
LDP Q6, Q7, [LR, #336]
|
LDP Q6, Q7, [LR, #(0xA0 + 16 * 6)]
|
||||||
LDP Q8, Q9, [LR, #368]
|
LDP Q8, Q9, [LR, #(0xA0 + 16 * 8)]
|
||||||
LDP Q10, Q11, [LR, #400]
|
LDP Q10, Q11, [LR, #(0xA0 + 16 * 10)]
|
||||||
LDP Q12, Q13, [LR, #432]
|
LDP Q12, Q13, [LR, #(0xA0 + 16 * 12)]
|
||||||
LDP Q14, Q15, [LR, #464]
|
LDP Q14, Q15, [LR, #(0xA0 + 16 * 14)]
|
||||||
LDP Q16, Q17, [LR, #496]
|
LDP Q16, Q17, [LR, #(0xA0 + 16 * 16)]
|
||||||
LDP Q18, Q19, [LR, #528]
|
LDP Q18, Q19, [LR, #(0xA0 + 16 * 18)]
|
||||||
LDP Q20, Q21, [LR, #560]
|
LDP Q20, Q21, [LR, #(0xA0 + 16 * 20)]
|
||||||
LDP Q22, Q23, [LR, #592]
|
LDP Q22, Q23, [LR, #(0xA0 + 16 * 22)]
|
||||||
LDP Q24, Q25, [LR, #624]
|
LDP Q24, Q25, [LR, #(0xA0 + 16 * 24)]
|
||||||
LDP Q26, Q27, [LR, #656]
|
LDP Q26, Q27, [LR, #(0xA0 + 16 * 26)]
|
||||||
LDP Q28, Q29, [LR, #688]
|
LDP Q28, Q29, [LR, #(0xA0 + 16 * 28)]
|
||||||
LDP Q30, Q31, [LR, #720]
|
LDP Q30, Q31, [LR, #(0xA0 + 16 * 30)]
|
||||||
|
|
||||||
/* Store FPCR/FPSR */
|
/* Store FPCR/FPSR */
|
||||||
MRS X0, FPSR
|
MRS X0, FPSR
|
||||||
STR W0, [LR, #744]
|
STR W0, [LR, #0x298]
|
||||||
MRS X1, FPCR
|
MRS X1, FPCR
|
||||||
STR W1, [LR, #748]
|
STR W1, [LR, #0x29C]
|
||||||
|
|
||||||
/* Load GP Registers */
|
/* Load GP Registers */
|
||||||
LDP X0, X1, [LR, #0]
|
LDP X0, X1, [LR, #(8 * 0)]
|
||||||
LDP X2, X3, [LR, #16]
|
LDP X2, X3, [LR, #(8 * 2)]
|
||||||
LDP X4, X5, [LR, #32]
|
LDP X4, X5, [LR, #(8 * 4)]
|
||||||
LDP X6, X7, [LR, #48]
|
LDP X6, X7, [LR, #(8 * 6)]
|
||||||
LDP X8, X9, [LR, #64]
|
LDP X8, X9, [LR, #(8 * 8)]
|
||||||
LDP X10, X11, [LR, #80]
|
LDP X10, X11, [LR, #(8 * 10)]
|
||||||
LDP X12, X13, [LR, #96]
|
LDP X12, X13, [LR, #(8 * 12)]
|
||||||
LDP X14, X15, [LR, #112]
|
LDP X14, X15, [LR, #(8 * 14)]
|
||||||
LDP X16, X17, [LR, #128]
|
LDP X16, X17, [LR, #(8 * 16)]
|
||||||
LDP X18, X19, [LR, #144]
|
LDR X18, [LR, #(8 * 18)]
|
||||||
LDP X20, X21, [LR, #160]
|
|
||||||
LDP X22, X23, [LR, #176]
|
|
||||||
LDP X24, X25, [LR, #192]
|
|
||||||
LDP X26, X27, [LR, #208]
|
|
||||||
LDP X28, X29, [LR, #224]
|
|
||||||
|
|
||||||
/* Restore Scratch Register */
|
/* Restore Scratch Register */
|
||||||
LDR LR, [SP, #8]
|
LDR LR, [SP, #8]
|
||||||
|
@ -1,280 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
|
||||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
|
||||||
|
|
||||||
#include <csignal>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <initializer_list> // This is used implicitly
|
|
||||||
#include <asm/siginfo.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <asm/unistd.h>
|
|
||||||
#include "guest_common.h"
|
|
||||||
|
|
||||||
namespace skyline::guest {
|
|
||||||
FORCE_INLINE void SaveCtxStack() {
|
|
||||||
asm("SUB SP, SP, #240\n\t"
|
|
||||||
"STP X0, X1, [SP, #0]\n\t"
|
|
||||||
"STP X2, X3, [SP, #16]\n\t"
|
|
||||||
"STP X4, X5, [SP, #32]\n\t"
|
|
||||||
"STP X6, X7, [SP, #48]\n\t"
|
|
||||||
"STP X8, X9, [SP, #64]\n\t"
|
|
||||||
"STP X10, X11, [SP, #80]\n\t"
|
|
||||||
"STP X12, X13, [SP, #96]\n\t"
|
|
||||||
"STP X14, X15, [SP, #112]\n\t"
|
|
||||||
"STP X16, X17, [SP, #128]\n\t"
|
|
||||||
"STP X18, X19, [SP, #144]\n\t"
|
|
||||||
"STP X20, X21, [SP, #160]\n\t"
|
|
||||||
"STP X22, X23, [SP, #176]\n\t"
|
|
||||||
"STP X24, X25, [SP, #192]\n\t"
|
|
||||||
"STP X26, X27, [SP, #208]\n\t"
|
|
||||||
"STP X28, X29, [SP, #224]"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCE_INLINE void LoadCtxStack() {
|
|
||||||
asm("LDP X0, X1, [SP, #0]\n\t"
|
|
||||||
"LDP X2, X3, [SP, #16]\n\t"
|
|
||||||
"LDP X4, X5, [SP, #32]\n\t"
|
|
||||||
"LDP X6, X7, [SP, #48]\n\t"
|
|
||||||
"LDP X8, X9, [SP, #64]\n\t"
|
|
||||||
"LDP X10, X11, [SP, #80]\n\t"
|
|
||||||
"LDP X12, X13, [SP, #96]\n\t"
|
|
||||||
"LDP X14, X15, [SP, #112]\n\t"
|
|
||||||
"LDP X16, X17, [SP, #128]\n\t"
|
|
||||||
"LDP X18, X19, [SP, #144]\n\t"
|
|
||||||
"LDP X20, X21, [SP, #160]\n\t"
|
|
||||||
"LDP X22, X23, [SP, #176]\n\t"
|
|
||||||
"LDP X24, X25, [SP, #192]\n\t"
|
|
||||||
"LDP X26, X27, [SP, #208]\n\t"
|
|
||||||
"LDP X28, X29, [SP, #224]\n\t"
|
|
||||||
"ADD SP, SP, #240"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCE_INLINE void SaveCtxTls() {
|
|
||||||
asm("STR LR, [SP, #-16]!\n\t"
|
|
||||||
"MRS LR, TPIDR_EL0\n\t"
|
|
||||||
"STP X0, X1, [LR, #16]\n\t"
|
|
||||||
"STP X2, X3, [LR, #32]\n\t"
|
|
||||||
"STP X4, X5, [LR, #48]\n\t"
|
|
||||||
"STP X6, X7, [LR, #64]\n\t"
|
|
||||||
"STP X8, X9, [LR, #80]\n\t"
|
|
||||||
"STP X10, X11, [LR, #96]\n\t"
|
|
||||||
"STP X12, X13, [LR, #112]\n\t"
|
|
||||||
"STP X14, X15, [LR, #128]\n\t"
|
|
||||||
"STP X16, X17, [LR, #144]\n\t"
|
|
||||||
"STP X18, X19, [LR, #160]\n\t"
|
|
||||||
"STP X20, X21, [LR, #176]\n\t"
|
|
||||||
"STP X22, X23, [LR, #192]\n\t"
|
|
||||||
"STP X24, X25, [LR, #208]\n\t"
|
|
||||||
"STP X26, X27, [LR, #224]\n\t"
|
|
||||||
"STP X28, X29, [LR, #240]\n\t"
|
|
||||||
"LDR LR, [SP], #16\n\t"
|
|
||||||
"DSB ST"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCE_INLINE void LoadCtxTls() {
|
|
||||||
asm("STR LR, [SP, #-16]!\n\t"
|
|
||||||
"MRS LR, TPIDR_EL0\n\t"
|
|
||||||
"LDP X0, X1, [LR, #16]\n\t"
|
|
||||||
"LDP X2, X3, [LR, #32]\n\t"
|
|
||||||
"LDP X4, X5, [LR, #48]\n\t"
|
|
||||||
"LDP X6, X7, [LR, #64]\n\t"
|
|
||||||
"LDP X8, X9, [LR, #80]\n\t"
|
|
||||||
"LDP X10, X11, [LR, #96]\n\t"
|
|
||||||
"LDP X12, X13, [LR, #112]\n\t"
|
|
||||||
"LDP X14, X15, [LR, #128]\n\t"
|
|
||||||
"LDP X16, X17, [LR, #144]\n\t"
|
|
||||||
"LDP X18, X19, [LR, #160]\n\t"
|
|
||||||
"LDP X20, X21, [LR, #176]\n\t"
|
|
||||||
"LDP X22, X23, [LR, #192]\n\t"
|
|
||||||
"LDP X24, X25, [LR, #208]\n\t"
|
|
||||||
"LDP X26, X27, [LR, #224]\n\t"
|
|
||||||
"LDP X28, X29, [LR, #240]\n\t"
|
|
||||||
"LDR LR, [SP], #16"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @note Do not use any functions that cannot be inlined from this, as this function is placed at an arbitrary address in the guest. In addition, do not use any static variables or globals as the .bss section is not copied into the guest.
|
|
||||||
*/
|
|
||||||
void SvcHandler(u64 pc, u16 svc) {
|
|
||||||
/*
|
|
||||||
volatile ThreadContext *ctx;
|
|
||||||
asm("MRS %0, TPIDR_EL0":"=r"(ctx));
|
|
||||||
|
|
||||||
ctx->pc = pc;
|
|
||||||
ctx->svc = svc;
|
|
||||||
|
|
||||||
if (svc == 0x1E) { // svcGetSystemTick
|
|
||||||
asm("STP X1, X2, [SP, #-16]!\n\t"
|
|
||||||
"STR Q0, [SP, #-16]!\n\t"
|
|
||||||
"STR Q1, [SP, #-16]!\n\t"
|
|
||||||
"STR Q2, [SP, #-16]!\n\t"
|
|
||||||
"MRS X1, CNTFRQ_EL0\n\t"
|
|
||||||
"MRS X2, CNTVCT_EL0\n\t"
|
|
||||||
"UCVTF D0, X0\n\t"
|
|
||||||
"MOV X1, 87411174408192\n\t"
|
|
||||||
"MOVK X1, 0x4172, LSL 48\n\t"
|
|
||||||
"FMOV D2, X1\n\t"
|
|
||||||
"UCVTF D1, X1\n\t"
|
|
||||||
"FDIV D0, D0, D2\n\t"
|
|
||||||
"FMUL D0, D0, D1\n\t"
|
|
||||||
"FCVTZU %0, D0\n\t"
|
|
||||||
"LDR Q2, [SP], #16\n\t"
|
|
||||||
"LDR Q1, [SP], #16\n\t"
|
|
||||||
"LDR Q0, [SP], #16\n\t"
|
|
||||||
"LDP X1, X2, [SP], #16"::"r"(ctx->registers.x0));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
ctx->state = ThreadState::WaitKernel;
|
|
||||||
|
|
||||||
while (ctx->state == ThreadState::WaitKernel);
|
|
||||||
|
|
||||||
if (ctx->state == ThreadState::WaitRun) {
|
|
||||||
break;
|
|
||||||
} else if (ctx->state == ThreadState::WaitFunc) {
|
|
||||||
if (ctx->threadCall == ThreadCall::Syscall) {
|
|
||||||
SaveCtxStack();
|
|
||||||
LoadCtxTls();
|
|
||||||
|
|
||||||
asm("STR LR, [SP, #-16]!\n\t"
|
|
||||||
"MOV LR, SP\n\t"
|
|
||||||
"SVC #0\n\t"
|
|
||||||
"MOV SP, LR\n\t"
|
|
||||||
"LDR LR, [SP], #16");
|
|
||||||
|
|
||||||
SaveCtxTls();
|
|
||||||
LoadCtxStack();
|
|
||||||
} else if (ctx->threadCall == ThreadCall::Memcopy) {
|
|
||||||
auto src{reinterpret_cast<u8 *>(ctx->registers.x0)};
|
|
||||||
auto dest{reinterpret_cast<u8 *>(ctx->registers.x1)};
|
|
||||||
auto size{ctx->registers.x2};
|
|
||||||
auto end{src + size};
|
|
||||||
|
|
||||||
while (src < end)
|
|
||||||
*(src++) = *(dest++);
|
|
||||||
} else if (ctx->threadCall == ThreadCall::Clone) {
|
|
||||||
SaveCtxStack();
|
|
||||||
LoadCtxTls();
|
|
||||||
|
|
||||||
asm("STR LR, [SP, #-16]!\n\t"
|
|
||||||
"MOV LR, SP\n\t"
|
|
||||||
"SVC #0\n\t"
|
|
||||||
"CBNZ X0, .parent\n\t"
|
|
||||||
"MSR TPIDR_EL0, X3\n\t"
|
|
||||||
"MOV LR, 0\n\t"
|
|
||||||
"MOV X0, X6\n\t"
|
|
||||||
"MOV X1, XZR\n\t"
|
|
||||||
"MOV X2, XZR\n\t"
|
|
||||||
"MOV X3, XZR\n\t"
|
|
||||||
"MOV X4, XZR\n\t"
|
|
||||||
"MOV X6, XZR\n\t"
|
|
||||||
"MOV X7, XZR\n\t"
|
|
||||||
"MOV X8, XZR\n\t"
|
|
||||||
"MOV X9, XZR\n\t"
|
|
||||||
"MOV X10, XZR\n\t"
|
|
||||||
"MOV X11, XZR\n\t"
|
|
||||||
"MOV X12, XZR\n\t"
|
|
||||||
"MOV X13, XZR\n\t"
|
|
||||||
"MOV X14, XZR\n\t"
|
|
||||||
"MOV X15, XZR\n\t"
|
|
||||||
"MOV X16, XZR\n\t"
|
|
||||||
"MOV X17, XZR\n\t"
|
|
||||||
"MOV X18, XZR\n\t"
|
|
||||||
"MOV X19, XZR\n\t"
|
|
||||||
"MOV X20, XZR\n\t"
|
|
||||||
"MOV X21, XZR\n\t"
|
|
||||||
"MOV X22, XZR\n\t"
|
|
||||||
"MOV X23, XZR\n\t"
|
|
||||||
"MOV X24, XZR\n\t"
|
|
||||||
"MOV X25, XZR\n\t"
|
|
||||||
"MOV X26, XZR\n\t"
|
|
||||||
"MOV X27, XZR\n\t"
|
|
||||||
"MOV X28, XZR\n\t"
|
|
||||||
"MOV X29, XZR\n\t"
|
|
||||||
"BR X5\n\t"
|
|
||||||
".parent:\n\t"
|
|
||||||
"MOV SP, LR\n\t"
|
|
||||||
"LDR LR, [SP], #16");
|
|
||||||
|
|
||||||
SaveCtxTls();
|
|
||||||
LoadCtxStack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->state = ThreadState::Running;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
[[noreturn]] void Exit(int) {
|
|
||||||
if (gettid() == getpid())
|
|
||||||
syscall(__NR_exit_group, 0);
|
|
||||||
else
|
|
||||||
syscall(__NR_exit, 0);
|
|
||||||
__builtin_unreachable();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[noreturn]] void SignalHandler(int signal, siginfo_t *info, ucontext_t *ucontext) {
|
|
||||||
/*
|
|
||||||
volatile ThreadContext *ctx;
|
|
||||||
asm("MRS %0, TPIDR_EL0":"=r"(ctx));
|
|
||||||
|
|
||||||
for (u8 index{}; index < 30; index++)
|
|
||||||
ctx->registers.regs[index] = ucontext->uc_mcontext.regs[index];
|
|
||||||
|
|
||||||
ctx->pc = ucontext->uc_mcontext.pc;
|
|
||||||
ctx->signal = static_cast<u32>(signal);
|
|
||||||
ctx->faultAddress = ucontext->uc_mcontext.fault_address;
|
|
||||||
ctx->sp = ucontext->uc_mcontext.sp;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
ctx->state = ThreadState::GuestCrash;
|
|
||||||
|
|
||||||
if (ctx->state == ThreadState::WaitRun)
|
|
||||||
Exit(0);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void GuestEntry(u64 address) {
|
|
||||||
/*
|
|
||||||
volatile ThreadContext *ctx;
|
|
||||||
asm("MRS %0, TPIDR_EL0":"=r"(ctx));
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
ctx->state = ThreadState::WaitInit;
|
|
||||||
while (ctx->state == ThreadState::WaitInit);
|
|
||||||
|
|
||||||
if (ctx->state == ThreadState::WaitRun) {
|
|
||||||
break;
|
|
||||||
} else if (ctx->state == ThreadState::WaitFunc) {
|
|
||||||
if (ctx->threadCall == ThreadCall::Syscall) {
|
|
||||||
SaveCtxStack();
|
|
||||||
LoadCtxTls();
|
|
||||||
|
|
||||||
asm("STR LR, [SP, #-16]!\n\t"
|
|
||||||
"MOV LR, SP\n\t"
|
|
||||||
"SVC #0\n\t"
|
|
||||||
"MOV SP, LR\n\t"
|
|
||||||
"LDR LR, [SP], #16");
|
|
||||||
|
|
||||||
SaveCtxTls();
|
|
||||||
LoadCtxStack();
|
|
||||||
}
|
|
||||||
} else if (ctx->threadCall == ThreadCall::Memcopy) {
|
|
||||||
auto src{reinterpret_cast<u8 *>(ctx->registers.x0)};
|
|
||||||
auto dest{reinterpret_cast<u8 *>(ctx->registers.x1)};
|
|
||||||
auto size{ctx->registers.x2};
|
|
||||||
auto end{src + size};
|
|
||||||
|
|
||||||
while (src < end)
|
|
||||||
*(src++) = *(dest++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,12 +9,12 @@ namespace skyline {
|
|||||||
struct DeviceState;
|
struct DeviceState;
|
||||||
namespace nce {
|
namespace nce {
|
||||||
/**
|
/**
|
||||||
* @brief The state of all the general purpose registers in the guest
|
* @brief The state of callee-saved general purpose registers in the guest
|
||||||
* @note Read about ARMv8 registers here: https://developer.arm.com/architectures/learn-the-architecture/armv8-a-instruction-set-architecture/registers-in-aarch64-general-purpose-registers
|
* @note Read about ARMv8 registers here: https://developer.arm.com/architectures/learn-the-architecture/armv8-a-instruction-set-architecture/registers-in-aarch64-general-purpose-registers
|
||||||
* @note X30 or LR is not provided as it is reserved for other uses
|
* @note Read about ARMv8 ABI here: https://github.com/ARM-software/abi-aa/blob/2f1ac56a7d79f3e753e6ca88d4d3e083c31d6f64/aapcs64/aapcs64.rst#machine-registers
|
||||||
*/
|
*/
|
||||||
union GpRegisters {
|
union GpRegisters {
|
||||||
std::array<u64, 30> regs;
|
std::array<u64, 19> regs;
|
||||||
struct {
|
struct {
|
||||||
u64 x0;
|
u64 x0;
|
||||||
u64 x1;
|
u64 x1;
|
||||||
@ -35,17 +35,6 @@ namespace skyline {
|
|||||||
u64 x16;
|
u64 x16;
|
||||||
u64 x17;
|
u64 x17;
|
||||||
u64 x18;
|
u64 x18;
|
||||||
u64 x19;
|
|
||||||
u64 x20;
|
|
||||||
u64 x21;
|
|
||||||
u64 x22;
|
|
||||||
u64 x23;
|
|
||||||
u64 x24;
|
|
||||||
u64 x25;
|
|
||||||
u64 x26;
|
|
||||||
u64 x27;
|
|
||||||
u64 x28;
|
|
||||||
u64 x29;
|
|
||||||
};
|
};
|
||||||
struct {
|
struct {
|
||||||
u32 w0;
|
u32 w0;
|
||||||
@ -86,36 +75,15 @@ namespace skyline {
|
|||||||
u32 __w17__;
|
u32 __w17__;
|
||||||
u32 w18;
|
u32 w18;
|
||||||
u32 __w18__;
|
u32 __w18__;
|
||||||
u32 w19;
|
|
||||||
u32 __w19__;
|
|
||||||
u32 w20;
|
|
||||||
u32 __w20__;
|
|
||||||
u32 w21;
|
|
||||||
u32 __w21__;
|
|
||||||
u32 w22;
|
|
||||||
u32 __w22__;
|
|
||||||
u32 w23;
|
|
||||||
u32 __w23__;
|
|
||||||
u32 w24;
|
|
||||||
u32 __w24__;
|
|
||||||
u32 w25;
|
|
||||||
u32 __w25__;
|
|
||||||
u32 w26;
|
|
||||||
u32 __w26__;
|
|
||||||
u32 w27;
|
|
||||||
u32 __w27__;
|
|
||||||
u32 w28;
|
|
||||||
u32 __w28__;
|
|
||||||
u32 w29;
|
|
||||||
u32 __w29__;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The state of all the floating point (and SIMD) registers in the guest
|
* @brief The state of all floating point (and SIMD) registers in the guest
|
||||||
* @note FPSR/FPCR are 64-bit system registers but only the lower 32-bits are used
|
* @note FPSR/FPCR are 64-bit system registers but only the lower 32-bits are used
|
||||||
|
* @note Read about ARMv8 ABI here: https://github.com/ARM-software/abi-aa/blob/2f1ac56a7d79f3e753e6ca88d4d3e083c31d6f64/aapcs64/aapcs64.rst#612simd-and-floating-point-registers
|
||||||
*/
|
*/
|
||||||
union FpRegisters {
|
union alignas(16) FpRegisters {
|
||||||
std::array<u128, 32> regs;
|
std::array<u128, 32> regs;
|
||||||
u32 fpsr;
|
u32 fpsr;
|
||||||
u32 fpcr;
|
u32 fpcr;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
#include <os.h>
|
|
||||||
#include <kernel/types/KProcess.h>
|
#include <kernel/types/KProcess.h>
|
||||||
#include <input.h>
|
#include <input.h>
|
||||||
#include "IHidServer.h"
|
#include "IHidServer.h"
|
||||||
|
@ -24,16 +24,16 @@ namespace skyline::service::hosbinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GraphicBufferProducer::DequeueBuffer(Parcel &in, Parcel &out) {
|
void GraphicBufferProducer::DequeueBuffer(Parcel &in, Parcel &out) {
|
||||||
u32 format{in.Pop<u32>()};
|
in.Pop<u32>(); //!< async boolean flag
|
||||||
u32 width{in.Pop<u32>()};
|
u32 width{in.Pop<u32>()};
|
||||||
u32 height{in.Pop<u32>()};
|
u32 height{in.Pop<u32>()};
|
||||||
u32 timestamp{in.Pop<u32>()};
|
u32 format{in.Pop<u32>()};
|
||||||
u32 usage{in.Pop<u32>()};
|
u32 usage{in.Pop<u32>()};
|
||||||
|
|
||||||
std::optional<u32> slot{std::nullopt};
|
std::optional<u32> slot{std::nullopt};
|
||||||
while (!slot) {
|
while (!slot) {
|
||||||
for (auto &buffer : queue) {
|
for (auto &buffer : queue) {
|
||||||
if (buffer.second->status == BufferStatus::Free && buffer.second->gbpBuffer.format == format && buffer.second->gbpBuffer.width == width && buffer.second->gbpBuffer.height == height && (buffer.second->gbpBuffer.usage & usage) == usage) {
|
if (buffer.second->status == BufferStatus::Free && (format ? buffer.second->gbpBuffer.format == format : true) && buffer.second->gbpBuffer.width == width && buffer.second->gbpBuffer.height == height && (buffer.second->gbpBuffer.usage & usage) == usage) {
|
||||||
slot = buffer.first;
|
slot = buffer.first;
|
||||||
buffer.second->status = BufferStatus::Dequeued;
|
buffer.second->status = BufferStatus::Dequeued;
|
||||||
break;
|
break;
|
||||||
@ -44,7 +44,7 @@ namespace skyline::service::hosbinder {
|
|||||||
out.Push(*slot);
|
out.Push(*slot);
|
||||||
out.Push(std::array<u32, 13>{1, 0x24}); // Unknown
|
out.Push(std::array<u32, 13>{1, 0x24}); // Unknown
|
||||||
|
|
||||||
state.logger->Debug("DequeueBuffer: Width: {}, Height: {}, Format: {}, Usage: {}, Timestamp: {}, Slot: {}", width, height, format, usage, timestamp, *slot);
|
state.logger->Debug("DequeueBuffer: Width: {}, Height: {}, Format: {}, Usage: {}, Slot: {}", width, height, format, usage, *slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicBufferProducer::QueueBuffer(Parcel &in, Parcel &out) {
|
void GraphicBufferProducer::QueueBuffer(Parcel &in, Parcel &out) {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
#include <os.h>
|
|
||||||
#include <kernel/types/KProcess.h>
|
#include <kernel/types/KProcess.h>
|
||||||
#include <gpu.h>
|
#include <gpu.h>
|
||||||
#include <services/nvdrv/driver.h>
|
#include <services/nvdrv/driver.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user