2014-07-24 01:07:07 +00:00
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2014-11-29 23:46:17 +00:00
|
|
|
#include <sys/kconfig.h>
|
2014-07-24 01:07:07 +00:00
|
|
|
#include <sys/kassert.h>
|
2014-10-15 01:02:19 +00:00
|
|
|
#include <sys/kmem.h>
|
2014-11-29 23:46:17 +00:00
|
|
|
#include <sys/mp.h>
|
2014-07-24 01:07:07 +00:00
|
|
|
#include <sys/thread.h>
|
2023-10-23 20:27:55 +00:00
|
|
|
#include <machine/cpu.h>
|
|
|
|
#include <machine/cpuop.h>
|
2014-07-24 01:07:07 +00:00
|
|
|
#include <machine/trap.h>
|
2015-01-17 01:57:21 +00:00
|
|
|
#include <machine/pmap.h>
|
2014-07-24 01:07:07 +00:00
|
|
|
|
2023-10-24 02:24:43 +00:00
|
|
|
extern TaskStateSegment64 TSS[MAX_CPUS];
|
|
|
|
extern Thread *curProc[MAX_CPUS];
|
|
|
|
extern Spinlock schedLock;
|
2014-07-24 01:07:07 +00:00
|
|
|
extern void switchstack(uint64_t *oldrsp, uint64_t rsp);
|
|
|
|
|
|
|
|
void
|
|
|
|
Thread_InitArch(Thread *thr)
|
|
|
|
{
|
2015-02-25 00:57:30 +00:00
|
|
|
thr->arch.useFP = true;
|
2014-07-24 01:07:07 +00:00
|
|
|
}
|
|
|
|
|
2023-10-24 02:24:43 +00:00
|
|
|
void
|
|
|
|
ThreadKThreadEntry(TrapFrame *tf) __NO_LOCK_ANALYSIS
|
|
|
|
{
|
|
|
|
TSS[CPU()].rsp0 = curProc[CPU()]->kstack + 4096;
|
|
|
|
|
|
|
|
Spinlock_Unlock(&schedLock);
|
|
|
|
|
|
|
|
Trap_Pop(tf);
|
|
|
|
}
|
|
|
|
|
2014-07-24 01:07:07 +00:00
|
|
|
void
|
2015-01-17 01:57:21 +00:00
|
|
|
Thread_SetupKThread(Thread *thr, void (*f)(),
|
|
|
|
uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
|
2014-07-24 01:07:07 +00:00
|
|
|
{
|
|
|
|
// Initialize stack
|
|
|
|
uint64_t stacktop = thr->kstack + PGSIZE;
|
|
|
|
ThreadArchStackFrame *sf;
|
|
|
|
TrapFrame *tf;
|
|
|
|
|
|
|
|
tf = (TrapFrame *)(stacktop - sizeof(*tf));
|
|
|
|
sf = (ThreadArchStackFrame *)(stacktop - sizeof(*tf) - sizeof(*sf));
|
|
|
|
thr->arch.rsp = (uint64_t)sf;
|
|
|
|
|
|
|
|
memset(tf, 0, sizeof(*tf));
|
|
|
|
memset(sf, 0, sizeof(*sf));
|
|
|
|
|
|
|
|
// Setup thread exit function on stack
|
|
|
|
|
|
|
|
sf->rip = (uint64_t)&ThreadKThreadEntry;
|
|
|
|
sf->rdi = (uint64_t)tf;
|
|
|
|
|
2014-11-26 21:49:17 +00:00
|
|
|
tf->ds = 0;
|
|
|
|
tf->ss = 0; //SEL_KDS;
|
2014-07-24 01:07:07 +00:00
|
|
|
tf->rsp = stacktop;
|
|
|
|
tf->cs = SEL_KCS;
|
|
|
|
tf->rip = (uint64_t)f;
|
2015-01-17 01:57:21 +00:00
|
|
|
tf->rdi = (uint64_t)arg1;
|
|
|
|
tf->rsi = (uint64_t)arg2;
|
|
|
|
tf->rdx = (uint64_t)arg3;
|
2014-07-24 01:07:07 +00:00
|
|
|
tf->rflags = RFLAGS_IF;
|
|
|
|
}
|
|
|
|
|
2015-01-06 01:06:35 +00:00
|
|
|
static void
|
2015-01-17 01:57:21 +00:00
|
|
|
ThreadEnterUserLevelCB(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
|
2015-01-06 01:06:35 +00:00
|
|
|
{
|
|
|
|
TrapFrame tf;
|
|
|
|
|
|
|
|
memset(&tf, 0, sizeof(tf));
|
|
|
|
tf.ds = SEL_UDS | 3;
|
2015-01-17 01:57:21 +00:00
|
|
|
tf.rip = (uint64_t)arg1;
|
2015-01-06 01:06:35 +00:00
|
|
|
tf.cs = SEL_UCS | 3;
|
2023-08-20 23:04:28 +00:00
|
|
|
tf.rsp = (uint64_t)arg2 + MEM_USERSPACE_STKLEN - PGSIZE;
|
2015-01-06 01:06:35 +00:00
|
|
|
tf.ss = SEL_UDS | 3;
|
|
|
|
tf.rflags = RFLAGS_IF;
|
2015-01-17 01:57:21 +00:00
|
|
|
tf.rdi = (uint64_t)arg3; /* Userspace Argument */
|
2015-01-06 01:06:35 +00:00
|
|
|
|
|
|
|
Trap_Pop(&tf);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-01-17 01:57:21 +00:00
|
|
|
Thread_SetupUThread(Thread *thr, uintptr_t rip, uintptr_t arg)
|
2015-01-06 01:06:35 +00:00
|
|
|
{
|
2015-01-17 01:57:21 +00:00
|
|
|
Thread_SetupKThread(thr, ThreadEnterUserLevelCB, rip,
|
|
|
|
thr->ustack, arg);
|
2015-01-06 01:06:35 +00:00
|
|
|
}
|
|
|
|
|
2014-07-24 01:07:07 +00:00
|
|
|
void
|
|
|
|
Thread_SwitchArch(Thread *oldthr, Thread *newthr)
|
|
|
|
{
|
2023-08-20 23:04:28 +00:00
|
|
|
/*
|
|
|
|
* Save and restore floating point and vector CPU state using the fxsave
|
|
|
|
* and fxrstor instructions.
|
|
|
|
*/
|
2014-07-24 01:07:07 +00:00
|
|
|
if (oldthr->arch.useFP)
|
|
|
|
{
|
|
|
|
fxsave(&oldthr->arch.xsa);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (newthr->arch.useFP)
|
|
|
|
{
|
|
|
|
fxrstor(&newthr->arch.xsa);
|
|
|
|
}
|
|
|
|
|
2015-02-25 00:57:30 +00:00
|
|
|
clts();
|
|
|
|
|
2014-07-24 01:07:07 +00:00
|
|
|
// Jump to trapframe
|
|
|
|
switchstack(&oldthr->arch.rsp, newthr->arch.rsp);
|
2014-11-29 23:46:17 +00:00
|
|
|
|
|
|
|
// Set new RSP0
|
|
|
|
TSS[CPU()].rsp0 = oldthr->kstack + 4096;
|
2014-07-24 01:07:07 +00:00
|
|
|
}
|
|
|
|
|