We can now change threads

This commit is contained in:
wheremyfoodat 2022-09-20 15:30:41 +03:00
parent 1678cd6172
commit 9b95bd87f1
10 changed files with 159 additions and 14 deletions

View file

@ -6,4 +6,61 @@
#error KVM CPU is not implemented yet
#else
#error No CPU core implemented :(
#endif
#endif
// Status register definitions
namespace CPSR {
enum : u32 {
// Privilege modes
UserMode = 16,
FIQMode = 17,
IRQMode = 18,
SVCMode = 19,
AbortMode = 23,
UndefMode = 27,
SystemMode = 31,
// If (CPSR & Thumb) the we're in thumb mode
Thumb = 1 << 5
};
}
namespace FPSCR {
// FPSCR Flags
enum : u32 {
NFlag = (1U << 31U), // Negative condition flag
ZFlag = (1 << 30), // Zero condition flag
CFlag = (1 << 29), // Carry condition flag
VFlag = (1 << 28), // Overflow condition flag
QC = (1 << 27), // Cumulative saturation bit
AHP = (1 << 26), // Alternative half-precision control bit
DefaultNan = (1 << 25), // Default NaN mode control bit
FlushToZero = (1 << 24), // Flush abnormals to 0 control bit
RmodeMask = (3 << 22), // Rounding Mode bit mask
StrideMask = (3 << 20), // Vector stride bit mask
LengthMask = (7 << 16), // Vector length bit mask
IDE = (1 << 15), // Input Denormal exception trap enable.
IXE = (1 << 12), // Inexact exception trap enable
UFE = (1 << 11), // Undeflow exception trap enable
OFE = (1 << 10), // Overflow exception trap enable
DZE = (1 << 9), // Division by Zero exception trap enable
IOE = (1 << 8), // Invalid Operation exception trap enable
IDC = (1 << 7), // Input Denormal cumulative exception bit
IXC = (1 << 4), // Inexact cumulative exception bit
UFC = (1 << 3), // Undeflow cumulative exception bit
OFC = (1 << 2), // Overflow cumulative exception bit
DZC = (1 << 1), // Division by Zero cumulative exception bit
IOC = (1 << 0), // Invalid Operation cumulative exception bit
RoundNearest = (0 << 22),
RoundPlusInf = (1 << 22),
RoundMinusInf = (2 << 22),
RoundToZero = (3 << 22),
// Default FPSCR value for threads
ThreadDefault = DefaultNan | FlushToZero | RoundToZero | IXC
};
}

View file

@ -119,6 +119,14 @@ public:
return jit->Regs();
}
// Get reference to array of FPRs. This array consists of the FPRs as single precision values
// Hence why its base type is u32
// Note: Dynarmic keeps 64 VFP registers as VFPv3 extends the VFP register set to 64 registers.
// However the 3DS ARM11 is an ARMv6k processor with VFPv2, so only the first 32 registers are actually used
std::array<u32, 64>& fprs() {
return jit->ExtRegs();
}
void setCPSR(u32 value) {
jit->SetCpsr(value);
}
@ -127,6 +135,19 @@ public:
return jit->Cpsr();
}
void setFPSCR(u32 value) {
jit->SetFpscr(value);
}
u32 getFPSCR() {
return jit->Fpscr();
}
// Set the base pointer to thread-local storage, stored in a CP15 register on the 3DS
void setTLSBase(u32 value) {
cp15->setTLSBase(value);
}
void runFrame() {
env.ticksLeft = 268111856 / 60;
const auto exitReason = jit->Run();

View file

@ -62,7 +62,10 @@ class CP15 final : public Dynarmic::A32::Coprocessor {
}
public:
void reset() {
threadStoragePointer = VirtualAddrs::TLSBase;
void setTLSBase(u32 value) {
threadStoragePointer = value;
}
// Currently does nothing but may be needed in the future
void reset() {}
};

View file

@ -6,6 +6,7 @@
#include "kernel_types.hpp"
#include "helpers.hpp"
#include "memory.hpp"
#include "resource_limits.hpp"
#include "services/service_manager.hpp"
class CPU;
@ -17,12 +18,13 @@ class Kernel {
// The handle number for the next kernel object to be created
u32 handleCounter;
std::array<Thread, appResourceLimits.maxThreads> threads;
std::vector<KernelObject> objects;
std::vector<Handle> portHandles;
Handle currentProcess;
Handle currentThread;
Handle mainThread;
int currentThreadIndex;
Handle srvHandle; // Handle for the special service manager port "srv:"
u32 arbiterCount;
u32 threadCount;
@ -64,6 +66,8 @@ class Kernel {
Handle makeSession(Handle port);
Handle makeThread(u32 entrypoint, u32 initialSP, u32 priority, u32 id, ThreadStatus status = ThreadStatus::Dormant);
void switchThread(int newThreadIndex);
std::optional<Handle> getPortHandle(const char* name);
void deleteObjectData(KernelObject& object);

View file

@ -1,4 +1,5 @@
#pragma once
#include <array>
#include <cstring>
#include "handles.hpp"
#include "helpers.hpp"
@ -101,11 +102,15 @@ struct Thread {
u32 entrypoint; // Initial r15 value
u32 priority;
u32 processorID;
ThreadStatus status;
Handle handle; // OS handle for this thread
Thread(u32 initialSP, u32 entrypoint, u32 priority, u32 processorID, ThreadStatus status = ThreadStatus::Dormant)
: initialSP(initialSP), entrypoint(entrypoint), priority(priority), processorID(processorID), status(status) {}
// Thread context used for switching between threads
std::array<u32, 16> gprs;
std::array<u32, 32> fprs; // Stored as u32 because dynarmic does it
u32 cpsr;
u32 fpscr;
u32 tlsBase; // Base pointer for thread-local storage
};
static const char* kernelObjectTypeToString(KernelObjectType t) {

View file

@ -1,5 +1,5 @@
#pragma once
#include "kernel_types.hpp"
#include "helpers.hpp"
// Values and resource limit structure taken from Citra