ctx switch and kenter/kexit
This commit is contained in:
parent
a1bf1cd7b4
commit
db8c734f4e
@ -61,6 +61,7 @@ src_arm64 = [
|
|||||||
"arm64/paging.c",
|
"arm64/paging.c",
|
||||||
"arm64/mrt/init.c",
|
"arm64/mrt/init.c",
|
||||||
"arm64/mrt/paging.c",
|
"arm64/mrt/paging.c",
|
||||||
|
"arm64/mrt/priv.c"
|
||||||
]
|
]
|
||||||
|
|
||||||
src_common = [
|
src_common = [
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
#define DECL_MRT(name) void MCODE name(void)
|
#define DECL_MRT(name) void MCODE name(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MGREG_MSTK (MCREG_MG16)
|
|
||||||
|
|
||||||
#if defined(IMPL_MRT)
|
#if defined(IMPL_MRT)
|
||||||
#undef IMPL_MRT
|
#undef IMPL_MRT
|
||||||
#define IMPL_MRT(name) int MCODE _ ## name ## _impl(void); \
|
#define IMPL_MRT(name) int MCODE _ ## name ## _impl(void); \
|
||||||
@ -21,38 +19,22 @@
|
|||||||
".globl " METAL_STR(name) ";" \
|
".globl " METAL_STR(name) ";" \
|
||||||
".balign 16;" \
|
".balign 16;" \
|
||||||
METAL_STR(name) ":;" \
|
METAL_STR(name) ":;" \
|
||||||
METAL_STR(RMCR_GAS(MGREG_MSTK, REG_X0)) ";" \
|
|
||||||
"mov x1, sp;" \
|
|
||||||
"str x1, [x0, #-16]!;" \
|
|
||||||
"mov sp, x0;" \
|
|
||||||
"mov x0, xzr;" \
|
"mov x0, xzr;" \
|
||||||
"ldr x0,=_" METAL_STR(name) "_impl;" \
|
"ldr x0,=_" METAL_STR(name) "_impl;" \
|
||||||
"blr x0;" \
|
"blr x0;" \
|
||||||
"ldr x1, [sp], #16;" \
|
|
||||||
"mov sp, x1;" \
|
|
||||||
METAL_STR(WMR_GAS(MREG_MR0, REG_X0)) ";" \
|
METAL_STR(WMR_GAS(MREG_MR0, REG_X0)) ";" \
|
||||||
METAL_STR(MEXIT_GAS(MREG_MR0)) ";" \
|
METAL_STR(MEXIT_GAS(MREG_MR0)) ";" \
|
||||||
); \
|
); \
|
||||||
int MCODE _ ## name ## _impl(void)
|
int MCODE _ ## name ## _impl(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IMPL_SHORT_MRT(name) int MCODE _ ## name ## _impl(void); \
|
|
||||||
__asm__ ( \
|
|
||||||
".section \"mcode\";" \
|
|
||||||
".globl " METAL_STR(name) ";" \
|
|
||||||
".balign 16;" \
|
|
||||||
METAL_STR(name) ":;" \
|
|
||||||
"mov x0, xzr;" \
|
|
||||||
"ldr x0,=_" METAL_STR(name) "_impl;" \
|
|
||||||
"blr x0;" \
|
|
||||||
METAL_STR(WMR_GAS(MREG_MR0, REG_X0)) ";" \
|
|
||||||
METAL_STR(MEXIT_GAS(MREG_MR0)) ";" \
|
|
||||||
); \
|
|
||||||
int MCODE _ ## name ## _impl(void)
|
|
||||||
|
|
||||||
#define DECL_MVAR(type, name) type MDATA name
|
#define DECL_MVAR(type, name) type MDATA name
|
||||||
#define DECL_MVAR_ALIGNED(type, name, align) type ALIGNED(align) MDATA name
|
#define DECL_MVAR_ALIGNED(type, name, align) type ALIGNED(align) MDATA name
|
||||||
|
|
||||||
#define MGREG_MPTB_DMAP (MCREG_MG19)
|
#define MGREG_MPTB_DMAP (MCREG_MG19)
|
||||||
#define MGREG_MPTB_XMEM (MCREG_MG18)
|
#define MGREG_MPTB_XMEM (MCREG_MG18)
|
||||||
#define MGREG_MPTB_USER (MCREG_MG17)
|
#define MGREG_MPTB_USER (MCREG_MG17)
|
||||||
|
#define MGREG_MCPL (MCREG_MG20)
|
||||||
|
#define MGREG_TMPRET (MCREG_MG21)
|
||||||
|
#define MCPL_KERNEL (0)
|
||||||
|
#define MCPL_USER (1)
|
||||||
|
@ -121,6 +121,7 @@
|
|||||||
#define MCREG_MEB (MCREG_MG3)
|
#define MCREG_MEB (MCREG_MG3)
|
||||||
#define MCREG_MTP (MCREG_MG4)
|
#define MCREG_MTP (MCREG_MG4)
|
||||||
#define MCREG_MAR (MCREG_MG5)
|
#define MCREG_MAR (MCREG_MG5)
|
||||||
|
#define MCREG_MSTK (MCREG_MG6)
|
||||||
|
|
||||||
#define _METAL_STR(x) #x
|
#define _METAL_STR(x) #x
|
||||||
#define METAL_STR(x) _METAL_STR(x)
|
#define METAL_STR(x) _METAL_STR(x)
|
||||||
|
@ -17,12 +17,15 @@ void MP_CrossCallTrap();
|
|||||||
int MP_CrossCall(CrossCallCB cb, void *arg);
|
int MP_CrossCall(CrossCallCB cb, void *arg);
|
||||||
|
|
||||||
struct CPUState {
|
struct CPUState {
|
||||||
|
vaddr_t kstack;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
uint32_t mpid;
|
uint32_t mpid;
|
||||||
uint32_t gic_redist_id;
|
uint32_t gic_redist_id;
|
||||||
volatile int state;
|
volatile int state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_Static_assert(offsetof(struct CPUState, kstack) == 0);
|
||||||
|
|
||||||
register uint64_t _cpu __asm__("x18");
|
register uint64_t _cpu __asm__("x18");
|
||||||
static inline unsigned int CPU(void)
|
static inline unsigned int CPU(void)
|
||||||
{
|
{
|
||||||
|
@ -38,6 +38,12 @@ DECL_MRT(mrt_set_mtp);
|
|||||||
DECL_MRT(mrt_wfi);
|
DECL_MRT(mrt_wfi);
|
||||||
#define MRT_WFI_IDX (6)
|
#define MRT_WFI_IDX (6)
|
||||||
|
|
||||||
|
DECL_MRT(mrt_kenter);
|
||||||
|
#define MRT_KENTER_IDX (7)
|
||||||
|
|
||||||
|
DECL_MRT(mrt_kexit);
|
||||||
|
#define MRT_KEXIT_IDX (8)
|
||||||
|
|
||||||
extern DECL_MVAR(struct mroutine_table, mtl_mrt_tbl);
|
extern DECL_MVAR(struct mroutine_table, mtl_mrt_tbl);
|
||||||
extern DECL_MVAR(struct exc_intercept_table, mtl_exc_tbl);
|
extern DECL_MVAR(struct exc_intercept_table, mtl_exc_tbl);
|
||||||
|
|
||||||
|
@ -6,11 +6,25 @@
|
|||||||
#include <machine/cpuop.h>
|
#include <machine/cpuop.h>
|
||||||
|
|
||||||
typedef struct ThreadArchStackFrame {
|
typedef struct ThreadArchStackFrame {
|
||||||
|
uint64_t r0;
|
||||||
|
uint64_t _r0;
|
||||||
|
uint64_t r19;
|
||||||
|
uint64_t r20;
|
||||||
|
uint64_t r21;
|
||||||
|
uint64_t r22;
|
||||||
|
uint64_t r23;
|
||||||
|
uint64_t r24;
|
||||||
|
uint64_t r25;
|
||||||
|
uint64_t r26;
|
||||||
|
uint64_t r27;
|
||||||
|
uint64_t r28;
|
||||||
|
uint64_t fp;
|
||||||
|
uint64_t lr;
|
||||||
} ThreadArchStackFrame;
|
} ThreadArchStackFrame;
|
||||||
|
_Static_assert(sizeof(ThreadArchStackFrame) % 16 == 0);
|
||||||
|
|
||||||
typedef struct ThreadArch {
|
typedef struct ThreadArch {
|
||||||
bool useFP;
|
uint64_t sp;
|
||||||
uint64_t rsp;
|
|
||||||
} ThreadArch;
|
} ThreadArch;
|
||||||
|
|
||||||
#endif /* __MACHINE_THREAD_H__ */
|
#endif /* __MACHINE_THREAD_H__ */
|
||||||
|
@ -114,7 +114,12 @@ typedef struct TrapFrame
|
|||||||
uint64_t r29;
|
uint64_t r29;
|
||||||
uint64_t r30;
|
uint64_t r30;
|
||||||
uint64_t r31;
|
uint64_t r31;
|
||||||
|
|
||||||
|
uint64_t pcpl;
|
||||||
|
uint64_t psp;
|
||||||
} TrapFrame;
|
} TrapFrame;
|
||||||
|
|
||||||
|
void Trap_Pop(struct TrapFrame * tf);
|
||||||
|
|
||||||
#endif /* __TRAP_H__ */
|
#endif /* __TRAP_H__ */
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ Machine_EarlyInit()
|
|||||||
static void
|
static void
|
||||||
Machine_IdleThread(UNUSED void *test)
|
Machine_IdleThread(UNUSED void *test)
|
||||||
{
|
{
|
||||||
while (1) { enable_interrupts(); hlt(); }
|
while (1) { kprintf("Idle Thread!\n"); enable_interrupts(); hlt(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,12 +138,6 @@ void Machine_Init()
|
|||||||
Panic("No boot disk!");
|
Panic("No boot disk!");
|
||||||
VFS_MountRoot(root);
|
VFS_MountRoot(root);
|
||||||
|
|
||||||
Critical_Exit();
|
|
||||||
|
|
||||||
while(1){
|
|
||||||
hlt();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the idle thread
|
* Create the idle thread
|
||||||
*/
|
*/
|
||||||
@ -153,6 +147,12 @@ void Machine_Init()
|
|||||||
}
|
}
|
||||||
Sched_SetRunnable(thr);
|
Sched_SetRunnable(thr);
|
||||||
|
|
||||||
|
Critical_Exit();
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
kprintf("Main thread!\n");
|
||||||
|
hlt();
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Load the init processor
|
* Load the init processor
|
||||||
*/
|
*/
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <machine/pmap.h>
|
#include <machine/pmap.h>
|
||||||
|
|
||||||
|
#define METAL_BOOTSTACK_SZ (4096)
|
||||||
|
DECL_MVAR_ALIGNED(static char, mtl_bootstack[METAL_BOOTSTACK_SZ], METAL_BOOTSTACK_SZ);
|
||||||
|
|
||||||
// early metal init
|
// early metal init
|
||||||
void mtl_init(void)
|
void mtl_init(void)
|
||||||
{
|
{
|
||||||
@ -10,6 +13,10 @@ void mtl_init(void)
|
|||||||
|
|
||||||
mtl_mrt_tbl.entries[MRT_INIT_IDX] = MRT_ENTRY_MAKE(mrt_init, 1);
|
mtl_mrt_tbl.entries[MRT_INIT_IDX] = MRT_ENTRY_MAKE(mrt_init, 1);
|
||||||
|
|
||||||
|
// load metal stack for the boot core
|
||||||
|
const regval_t mstk = (regval_t)(mtl_bootstack + METAL_BOOTSTACK_SZ);
|
||||||
|
WMCR(MCREG_MSTK, mstk);
|
||||||
|
|
||||||
// load mroutine table
|
// load mroutine table
|
||||||
WMCR(MCREG_MBR, &mtl_mrt_tbl);
|
WMCR(MCREG_MBR, &mtl_mrt_tbl);
|
||||||
|
|
||||||
|
@ -6,15 +6,13 @@
|
|||||||
DECL_MVAR(struct mroutine_table, mtl_mrt_tbl);
|
DECL_MVAR(struct mroutine_table, mtl_mrt_tbl);
|
||||||
DECL_MVAR(struct exc_intercept_table, mtl_exc_tbl);
|
DECL_MVAR(struct exc_intercept_table, mtl_exc_tbl);
|
||||||
DECL_MVAR(struct inst_intercept_table, mtl_inst_tbl);
|
DECL_MVAR(struct inst_intercept_table, mtl_inst_tbl);
|
||||||
#define METAL_BOOTSTACK_SZ (4096)
|
|
||||||
DECL_MVAR_ALIGNED(static char, mtl_bootstack[METAL_BOOTSTACK_SZ], METAL_BOOTSTACK_SZ);
|
|
||||||
|
|
||||||
IMPL_SHORT_MRT(mrt_dummy)
|
IMPL_MRT(mrt_dummy)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_SHORT_MRT(mrt_wfi)
|
IMPL_MRT(mrt_wfi)
|
||||||
{
|
{
|
||||||
unsigned int times;
|
unsigned int times;
|
||||||
MRT_GETARG(0, times);
|
MRT_GETARG(0, times);
|
||||||
@ -30,7 +28,7 @@ IMPL_SHORT_MRT(mrt_wfi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_SHORT_MRT(mrt_init)
|
IMPL_MRT(mrt_init)
|
||||||
{
|
{
|
||||||
memset(&mtl_mrt_tbl, 0, sizeof(mtl_mrt_tbl));
|
memset(&mtl_mrt_tbl, 0, sizeof(mtl_mrt_tbl));
|
||||||
memset(&mtl_exc_tbl, 0, sizeof(mtl_exc_tbl));
|
memset(&mtl_exc_tbl, 0, sizeof(mtl_exc_tbl));
|
||||||
@ -44,6 +42,8 @@ IMPL_SHORT_MRT(mrt_init)
|
|||||||
mtl_mrt_tbl.entries[MRT_SET_MPTB_IDX] = MRT_ENTRY_MAKE(mrt_set_mptb, 1);
|
mtl_mrt_tbl.entries[MRT_SET_MPTB_IDX] = MRT_ENTRY_MAKE(mrt_set_mptb, 1);
|
||||||
mtl_mrt_tbl.entries[MRT_SET_MTP_IDX] = MRT_ENTRY_MAKE(mrt_set_mtp, 1);
|
mtl_mrt_tbl.entries[MRT_SET_MTP_IDX] = MRT_ENTRY_MAKE(mrt_set_mtp, 1);
|
||||||
mtl_mrt_tbl.entries[MRT_WFI_IDX] = MRT_ENTRY_MAKE(mrt_wfi, 1);
|
mtl_mrt_tbl.entries[MRT_WFI_IDX] = MRT_ENTRY_MAKE(mrt_wfi, 1);
|
||||||
|
mtl_mrt_tbl.entries[MRT_KENTER_IDX] = MRT_ENTRY_MAKE(mrt_kenter, 1);
|
||||||
|
mtl_mrt_tbl.entries[MRT_KEXIT_IDX] = MRT_ENTRY_MAKE(mrt_kexit, 1);
|
||||||
|
|
||||||
mtl_exc_tbl.entries[0].esrbits = (0b100100 << 26) | (0b00100); // data abort, lv0 translation
|
mtl_exc_tbl.entries[0].esrbits = (0b100100 << 26) | (0b00100); // data abort, lv0 translation
|
||||||
mtl_exc_tbl.entries[0].esrmask = (0b111111 << 26) | (0b11111);
|
mtl_exc_tbl.entries[0].esrmask = (0b111111 << 26) | (0b11111);
|
||||||
@ -111,9 +111,9 @@ IMPL_SHORT_MRT(mrt_init)
|
|||||||
msr |= (1ull << 60);
|
msr |= (1ull << 60);
|
||||||
WMCR(MCREG_MSR, msr);
|
WMCR(MCREG_MSR, msr);
|
||||||
|
|
||||||
// temporary metal stack
|
// set cpl = 0
|
||||||
regval_t mstk = (regval_t)&mtl_bootstack[METAL_BOOTSTACK_SZ];
|
regval_t zero = 0;
|
||||||
WMCR(MGREG_MSTK, mstk);
|
WMCR(MGREG_MCPL, zero);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
72
sys/arm64/mrt/priv.c
Normal file
72
sys/arm64/mrt/priv.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#include <machine/metal.h>
|
||||||
|
#include <machine/mrt.h>
|
||||||
|
#include <machine/paging.h>
|
||||||
|
#include <machine/mp.h>
|
||||||
|
#include <sys/thread.h>
|
||||||
|
|
||||||
|
extern Thread *curProc[MAX_CPUS];
|
||||||
|
|
||||||
|
IMPL_MRT(mrt_kenter)
|
||||||
|
{
|
||||||
|
regval_t pcpl;
|
||||||
|
RMCR(MGREG_MCPL, pcpl);
|
||||||
|
|
||||||
|
regval_t kstack_top, psp;
|
||||||
|
psp = SYSREG_GET(sp_el1);
|
||||||
|
if (pcpl == MCPL_USER) {
|
||||||
|
// switch MTP
|
||||||
|
const regval_t kmtp = MTP_KERNEL;
|
||||||
|
WMCR(MCREG_MTP, kmtp);
|
||||||
|
|
||||||
|
// switch to kernel stack
|
||||||
|
struct CPUState * state = (struct CPUState *)SYSREG_GET(tpidr_el1);
|
||||||
|
const uint32_t id = state->id;
|
||||||
|
kstack_top = curProc[id]->kstack + PGSIZE;
|
||||||
|
|
||||||
|
const regval_t kcpl = MCPL_KERNEL;
|
||||||
|
WMCR(MGREG_MCPL, kcpl);
|
||||||
|
} else {
|
||||||
|
// we already in kernel mode
|
||||||
|
kstack_top = SYSREG_GET(sp_el1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// store var onto the current kstack
|
||||||
|
// [kstack top] = pcpl
|
||||||
|
// [kstack top] + 8 = psp
|
||||||
|
kstack_top = kstack_top - 2 * sizeof(regval_t);
|
||||||
|
*(regval_t *)kstack_top = pcpl;
|
||||||
|
*(regval_t *)(kstack_top + sizeof(regval_t)) = psp;
|
||||||
|
SYSREG_SET(sp_el1, kstack_top);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPL_MRT(mrt_kexit)
|
||||||
|
{
|
||||||
|
regval_t cpl;
|
||||||
|
RMCR(MGREG_MCPL, cpl);
|
||||||
|
ASSERT(cpl == MCPL_KERNEL);
|
||||||
|
|
||||||
|
// [kstack top] = pcpl
|
||||||
|
// [kstack top] + 8 = psp
|
||||||
|
regval_t kstack_top = SYSREG_GET(sp_el1);
|
||||||
|
const regval_t psp = *(regval_t *)(kstack_top + sizeof(regval_t));
|
||||||
|
const regval_t pcpl = *(regval_t *)(kstack_top);
|
||||||
|
kstack_top += 2 * sizeof(regval_t);
|
||||||
|
|
||||||
|
if (pcpl == MCPL_USER) {
|
||||||
|
// we are going back to usermode
|
||||||
|
|
||||||
|
// switch MTP to user
|
||||||
|
const regval_t kmtp = MTP_USER;
|
||||||
|
WMCR(MCREG_MTP, kmtp);
|
||||||
|
|
||||||
|
const regval_t kcpl = MCPL_USER;
|
||||||
|
WMCR(MGREG_MCPL, kcpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore previous stack ptr
|
||||||
|
SYSREG_SET(sp_el1, psp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -74,6 +74,9 @@ void vm_early_paging_init()
|
|||||||
SYSREG_SET(ttbr0_el1, zero);
|
SYSREG_SET(ttbr0_el1, zero);
|
||||||
SYSREG_SET(ttbr1_el1, zero);
|
SYSREG_SET(ttbr1_el1, zero);
|
||||||
|
|
||||||
|
// set MCPL to 0
|
||||||
|
|
||||||
|
|
||||||
// reset page tables
|
// reset page tables
|
||||||
flushtlb();
|
flushtlb();
|
||||||
}
|
}
|
150
sys/arm64/pmap.c
150
sys/arm64/pmap.c
@ -124,6 +124,26 @@ PMap_NewAS()
|
|||||||
return as;
|
return as;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pmap_destroy_vmpt(struct vmpt * const pt)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < VM_PTBUCKETS; i++) {
|
||||||
|
paddr_t curp = pt->entries[i].first;
|
||||||
|
|
||||||
|
while(curp != 0) {
|
||||||
|
struct vmpd * const cur = (struct vmpd *)DMPA2VA(curp);
|
||||||
|
const paddr_t pnext = cur->next;
|
||||||
|
|
||||||
|
pdcache_free(cur);
|
||||||
|
|
||||||
|
curp = pnext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// release vmpt
|
||||||
|
PAlloc_Release(pt);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PMap_DestroyAS --
|
* PMap_DestroyAS --
|
||||||
*
|
*
|
||||||
@ -135,13 +155,10 @@ void
|
|||||||
PMap_DestroyAS(AS *space)
|
PMap_DestroyAS(AS *space)
|
||||||
{
|
{
|
||||||
// free usertables
|
// free usertables
|
||||||
UNUSED struct vmpt * pt = space->user_tbl;
|
pmap_destroy_vmpt(space->user_tbl);
|
||||||
|
|
||||||
// release space itself
|
// release space itself
|
||||||
PAlloc_Release(space);
|
PAlloc_Release(space);
|
||||||
|
|
||||||
// XXX: release all pdcaches
|
|
||||||
NOT_IMPLEMENTED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -205,7 +222,7 @@ PMap_LoadAS(AS *space)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
PMap_MapPage(uint64_t phys, uint64_t virt, uint64_t pages, uint32_t pgshift, struct vmpt * tbl, uint64_t flags)
|
PMap_MapPage(paddr_t phys, vaddr_t virt, size_t pages, uint32_t pgshift, struct vmpt * tbl, uint64_t flags)
|
||||||
{
|
{
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
while (i < pages) {
|
while (i < pages) {
|
||||||
@ -229,6 +246,59 @@ PMap_MapPage(uint64_t phys, uint64_t virt, uint64_t pages, uint32_t pgshift, str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
PMap_FindVmpd(struct vmpte * pte, vaddr_t virt, uint32_t pgshift, struct vmpd ** curout, struct vmpd ** prevout)
|
||||||
|
{
|
||||||
|
paddr_t curp = pte->first;
|
||||||
|
struct vmpd * prev = NULL;
|
||||||
|
while (curp != 0) {
|
||||||
|
struct vmpd * const cur = (struct vmpd *)DMPA2VA(curp);
|
||||||
|
if (vm_get_pfn(cur->vaddr, pgshift) == vm_get_pfn(virt, pgshift)) {
|
||||||
|
if (prevout != NULL) {
|
||||||
|
*prevout = prev;
|
||||||
|
}
|
||||||
|
if (curout != NULL) {
|
||||||
|
*curout = cur;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = cur;
|
||||||
|
curp = cur->next;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
PMap_UnmapPage(vaddr_t virt, size_t pages, uint32_t pgshift, struct vmpt * tbl)
|
||||||
|
{
|
||||||
|
ASSERT((virt & ((1ull << pgshift) - 1)) == 0);
|
||||||
|
|
||||||
|
for (uint64_t i = 0; i < pages; i++) {
|
||||||
|
const vaddr_t va = virt + i * (1ull << pgshift);
|
||||||
|
const uint64_t pfn = vm_get_pfn(va, pgshift);
|
||||||
|
const uint64_t hash = vm_vahash(pfn);
|
||||||
|
ASSERT(hash < VM_PTBUCKETS);
|
||||||
|
struct vmpte * const pte = &tbl->entries[hash];
|
||||||
|
|
||||||
|
struct vmpd *found, *prev;
|
||||||
|
if (!PMap_FindVmpd(pte, virt, pgshift, &found, &prev)) {
|
||||||
|
Panic("Unmapping an unmapped vaddr.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// detach the node
|
||||||
|
if (prev == NULL) {
|
||||||
|
// first node
|
||||||
|
pte->first = found->next;
|
||||||
|
} else {
|
||||||
|
prev->next = found->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// free the unmapped pd
|
||||||
|
pdcache_free(found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PMap_Translate --
|
* PMap_Translate --
|
||||||
@ -239,12 +309,39 @@ PMap_MapPage(uint64_t phys, uint64_t virt, uint64_t pages, uint32_t pgshift, str
|
|||||||
* @param [in] va Virtual address we wish to translate.
|
* @param [in] va Virtual address we wish to translate.
|
||||||
*/
|
*/
|
||||||
uintptr_t
|
uintptr_t
|
||||||
PMap_Translate(UNUSED AS *space, UNUSED uintptr_t va)
|
PMap_Translate(AS *space, uintptr_t va)
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED();
|
struct vmpt * tbl;
|
||||||
|
uint32_t pgshift;
|
||||||
|
if (va >= MEM_USERSPACE_BASE && va < MEM_USERSPACE_TOP) {
|
||||||
|
tbl = space->user_tbl;
|
||||||
|
pgshift = PGSHIFT;
|
||||||
|
} else if (va >= MEM_DIRECTMAP_BASE && va < MEM_DIRECTMAP_TOP) {
|
||||||
|
tbl = space->dmap_tbl;
|
||||||
|
pgshift = LARGE_PGSHIFT;
|
||||||
|
} else if (va >= MEM_XMAP_BASE && va < MEM_XMAP_TOP) {
|
||||||
|
tbl = space->xmem_tbl;
|
||||||
|
pgshift = PGSHIFT;
|
||||||
|
} else {
|
||||||
|
kprintf("Trying to translate non-canonical vaddr 0x%lx.\n", va);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint64_t pfn = vm_get_pfn(va, pgshift);
|
||||||
|
const uint64_t hash = vm_vahash(pfn);
|
||||||
|
ASSERT(hash < VM_PTBUCKETS);
|
||||||
|
struct vmpte * const pte = &tbl->entries[hash];
|
||||||
|
const vaddr_t base = va & ~((1ull << pgshift) - 1);
|
||||||
|
|
||||||
|
struct vmpd * found;
|
||||||
|
if (!PMap_FindVmpd(pte, base, pgshift, &found, NULL)) {
|
||||||
|
kprintf("Trying to translate unmapped vaddr 0x%lx.\n", va);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return found->paddr + (va - base);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PMap_Map --
|
* PMap_Map --
|
||||||
*
|
*
|
||||||
@ -285,9 +382,14 @@ PMap_Map(AS *as, uint64_t phys, uint64_t virt, uint64_t pages, uint64_t flags)
|
|||||||
* @retval false On failure
|
* @retval false On failure
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
PMap_Unmap(UNUSED AS *as, UNUSED uint64_t va, UNUSED uint64_t pages)
|
PMap_Unmap(AS *as, uint64_t va, uint64_t pages)
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED();
|
// virt address must be within the usermap region
|
||||||
|
if (va < MEM_USERSPACE_BASE || va + pages * PGSIZE > MEM_USERSPACE_TOP) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PMap_UnmapPage(va, pages, PGSHIFT, as->user_tbl);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,9 +408,25 @@ PMap_Unmap(UNUSED AS *as, UNUSED uint64_t va, UNUSED uint64_t pages)
|
|||||||
* @retval false On failure
|
* @retval false On failure
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
PMap_AllocMap(UNUSED AS *as, UNUSED uint64_t virt, UNUSED uint64_t len, UNUSED uint64_t flags)
|
PMap_AllocMap(AS *as, uint64_t virt, uint64_t len, uint64_t flags)
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED();
|
ASSERT((virt & PGMASK) == 0);
|
||||||
|
|
||||||
|
if (virt + len > MEM_USERSPACE_TOP || virt < MEM_USERSPACE_BASE) {
|
||||||
|
// not in userspace
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t pages = ROUNDUP(len, PGSIZE) / PGSIZE;
|
||||||
|
const uint64_t padattr = PMapProtToPdattr(flags, false);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < pages; i++) {
|
||||||
|
const vaddr_t va = virt + PGSIZE * i;
|
||||||
|
|
||||||
|
const void *pg = PAlloc_AllocPage();
|
||||||
|
PMap_MapPage(DMVA2PA(pg), va, 1, PGSHIFT, as->user_tbl, padattr);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,12 +505,18 @@ PMap_SystemMap(uint64_t phys, uint64_t virt, uint64_t pages, uint64_t flags)
|
|||||||
* We do not currently use this!
|
* We do not currently use this!
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
PMap_SystemUnmap(UNUSED uint64_t virt, UNUSED uint64_t pages)
|
PMap_SystemUnmap(uint64_t virt, uint64_t pages)
|
||||||
{
|
{
|
||||||
NOT_IMPLEMENTED();
|
// virt address must be within the xmem region
|
||||||
|
if (virt < MEM_XMAP_BASE || virt + pages * PGSIZE > MEM_XMAP_TOP) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PMap_UnmapPage(virt, pages, PGSHIFT, systemAS.xmem_tbl);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PMap_Dump(UNUSED AS *space)
|
PMap_Dump(UNUSED AS *space)
|
||||||
{
|
{
|
||||||
|
@ -7,13 +7,30 @@
|
|||||||
.text
|
.text
|
||||||
|
|
||||||
# switch(uint64_t *oldsp, uint64_t newsp)
|
# switch(uint64_t *oldsp, uint64_t newsp)
|
||||||
# %rdi: oldsp
|
# %x0: oldsp
|
||||||
# %rsi: newsp
|
# %x1: newsp
|
||||||
FUNC_BEGIN(switchstack)
|
FUNC_BEGIN(switchstack)
|
||||||
# Save callee saved registers of old thread
|
# Save callee saved registers of old thread
|
||||||
|
stp fp, lr, [sp, #-16]!
|
||||||
|
stp x27, x28, [sp, #-16]!
|
||||||
|
stp x25, x26, [sp, #-16]!
|
||||||
|
stp x23, x24, [sp, #-16]!
|
||||||
|
stp x21, x22, [sp, #-16]!
|
||||||
|
stp x19, x20, [sp, #-16]!
|
||||||
|
stp x0, x0, [sp, #-16]!
|
||||||
|
|
||||||
# Switch stack from old to new thread
|
# Switch stack from old to new thread
|
||||||
|
mov x9, sp
|
||||||
|
str x9, [x0]
|
||||||
|
mov sp, x1
|
||||||
|
|
||||||
# Restore callee saved registers of new thread
|
# Restore callee saved registers of new thread
|
||||||
|
ldp x0, x0, [sp], #16
|
||||||
|
ldp x19, x20, [sp], #16
|
||||||
|
ldp x21, x22, [sp], #16
|
||||||
|
ldp x23, x24, [sp], #16
|
||||||
|
ldp x25, x26, [sp], #16
|
||||||
|
ldp x27, x28, [sp], #16
|
||||||
|
ldp fp, lr, [sp], #16
|
||||||
FUNC_END(switchstack)
|
FUNC_END(switchstack)
|
||||||
|
|
||||||
|
@ -13,19 +13,29 @@
|
|||||||
#include <machine/cpuop.h>
|
#include <machine/cpuop.h>
|
||||||
#include <machine/trap.h>
|
#include <machine/trap.h>
|
||||||
#include <machine/pmap.h>
|
#include <machine/pmap.h>
|
||||||
|
#include <machine/metal.h>
|
||||||
|
|
||||||
extern void ThreadKThreadEntry(TrapFrame *tf);
|
extern void switchstack(uint64_t *oldsp, uint64_t sp);
|
||||||
extern void switchstack(uint64_t *oldrsp, uint64_t rsp);
|
extern Spinlock schedLock;
|
||||||
|
|
||||||
void
|
void
|
||||||
Thread_InitArch(Thread *thr)
|
Thread_InitArch(Thread *thr)
|
||||||
{
|
{
|
||||||
thr->arch.useFP = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Thread_SetupKThread(Thread *thr, UNUSED void (*f)(void *),
|
ThreadKThreadEntry(TrapFrame *tf) __NO_LOCK_ANALYSIS
|
||||||
UNUSED uintptr_t arg1, UNUSED uintptr_t arg2, UNUSED uintptr_t arg3)
|
{
|
||||||
|
Spinlock_Unlock(&schedLock);
|
||||||
|
kprintf("tf in entry = 0x%p, elr = 0x%lx\n", tf, tf->elr);
|
||||||
|
Trap_Pop(tf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SPSR_EL1H_DAIF0 (0b101)
|
||||||
|
|
||||||
|
void
|
||||||
|
Thread_SetupKThread(Thread *thr, kthread_entry f,
|
||||||
|
uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
|
||||||
{
|
{
|
||||||
// Initialize stack
|
// Initialize stack
|
||||||
uint64_t stacktop = thr->kstack + PGSIZE;
|
uint64_t stacktop = thr->kstack + PGSIZE;
|
||||||
@ -34,35 +44,54 @@ Thread_SetupKThread(Thread *thr, UNUSED void (*f)(void *),
|
|||||||
|
|
||||||
tf = (TrapFrame *)(stacktop - sizeof(*tf));
|
tf = (TrapFrame *)(stacktop - sizeof(*tf));
|
||||||
sf = (ThreadArchStackFrame *)(stacktop - sizeof(*tf) - sizeof(*sf));
|
sf = (ThreadArchStackFrame *)(stacktop - sizeof(*tf) - sizeof(*sf));
|
||||||
|
thr->arch.sp = (uint64_t)sf;
|
||||||
|
|
||||||
memset(tf, 0, sizeof(*tf));
|
memset(tf, 0, sizeof(*tf));
|
||||||
memset(sf, 0, sizeof(*sf));
|
memset(sf, 0, sizeof(*sf));
|
||||||
|
|
||||||
// Setup thread exit function on stack
|
// Setup thread exit function on stack
|
||||||
|
sf->lr = (uint64_t)&ThreadKThreadEntry;
|
||||||
|
sf->r0 = (uint64_t)tf;
|
||||||
|
sf->_r0 = (uint64_t)tf;
|
||||||
|
kprintf("tf before entry = 0x%p\n", tf);
|
||||||
|
|
||||||
|
// interrupt enable
|
||||||
|
tf->spsr = SPSR_EL1H_DAIF0; // el1h, enable interrupts
|
||||||
|
tf->elr = (regval_t)f;
|
||||||
|
tf->pcpl = MCPL_KERNEL;
|
||||||
|
tf->psp = stacktop;
|
||||||
|
tf->r0 = (regval_t)arg1;
|
||||||
|
tf->r1 = (regval_t)arg2;
|
||||||
|
tf->r2 = (regval_t)arg3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ThreadEnterUserLevelCB(UNUSED void * unused)
|
ThreadEnterUserLevelCB(vaddr_t entry, vaddr_t ustack, vaddr_t args)
|
||||||
{
|
{
|
||||||
TrapFrame tf;
|
TrapFrame tf;
|
||||||
|
|
||||||
memset(&tf, 0, sizeof(tf));
|
memset(&tf, 0, sizeof(tf));
|
||||||
|
tf.elr = entry;
|
||||||
|
tf.r0 = args;
|
||||||
|
tf.psp = ustack + MEM_USERSPACE_STKLEN - PGSIZE;
|
||||||
|
tf.spsr = SPSR_EL1H_DAIF0;
|
||||||
|
tf.pcpl = MCPL_USER;
|
||||||
|
|
||||||
//Trap_Pop(&tf);
|
Trap_Pop(&tf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Thread_SetupUThread(Thread *thr, uintptr_t rip, uintptr_t arg)
|
Thread_SetupUThread(Thread *thr, uintptr_t rip, uintptr_t arg)
|
||||||
{
|
{
|
||||||
Thread_SetupKThread(thr, ThreadEnterUserLevelCB, rip,
|
Thread_SetupKThread(thr, (kthread_entry)ThreadEnterUserLevelCB, rip,
|
||||||
thr->ustack, arg);
|
thr->ustack, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Thread_SwitchArch(Thread *oldthr, Thread *newthr)
|
Thread_SwitchArch(Thread *oldthr, Thread *newthr)
|
||||||
{
|
{
|
||||||
|
kprintf("switch stack! oldthr sp = 0x%lx, newthr sp = 0x%lx\n", oldthr->arch.sp, newthr->arch.sp);
|
||||||
// Jump to trapframe
|
// Jump to trapframe
|
||||||
switchstack(&oldthr->arch.rsp, newthr->arch.rsp);
|
switchstack(&oldthr->arch.sp, newthr->arch.sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
// hardcode to 2024/03/14 12:34:56 AM EST
|
// hardcode to 2024/03/14 12:34:56 AM EST
|
||||||
#define KTIMER_EPOCH (1710390896ull)
|
#define KTIMER_EPOCH (1710390896ull)
|
||||||
|
|
||||||
|
extern void Sched_Scheduler(void);
|
||||||
|
|
||||||
static struct IRQHandler _irqh;
|
static struct IRQHandler _irqh;
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -34,8 +36,9 @@ PTimer_Tick(UNUSED void * arg)
|
|||||||
gic_send_eoi(KTIMER_IRQ);
|
gic_send_eoi(KTIMER_IRQ);
|
||||||
|
|
||||||
KTimer_Process();
|
KTimer_Process();
|
||||||
|
|
||||||
kprintf("Hardware timer tick, epoch = %lu, tsc = %lu, CVAL = %lu.\n", KTime_GetEpoch(), Time_GetTSC(), SYSREG_GET(CNTP_CVAL_EL0));
|
kprintf("Hardware timer tick, epoch = %lu, tsc = %lu, CVAL = %lu.\n", KTime_GetEpoch(), Time_GetTSC(), SYSREG_GET(CNTP_CVAL_EL0));
|
||||||
|
|
||||||
|
Sched_Scheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -102,6 +102,7 @@ extern void copystr_unsafe_fault(void);
|
|||||||
void
|
void
|
||||||
trap_entry(TrapFrame * tf)
|
trap_entry(TrapFrame * tf)
|
||||||
{
|
{
|
||||||
|
// kprintf("Trap: psp = 0x%lx, pcpl = %lu\n", tf->psp, tf->pcpl);
|
||||||
if (tf->type == T_TYPE_EXC) {
|
if (tf->type == T_TYPE_EXC) {
|
||||||
Panic("Unexpected exception: Type = 0x%lx, IntID = 0x%lx, ESR = 0x%lx, FAR = 0x%lx, ELR = 0x%lx, SPSR = 0x%lx.\n", tf->type, tf->intid, tf->esr, tf->far, tf->elr, tf->spsr);
|
Panic("Unexpected exception: Type = 0x%lx, IntID = 0x%lx, ESR = 0x%lx, FAR = 0x%lx, ELR = 0x%lx, SPSR = 0x%lx.\n", tf->type, tf->intid, tf->esr, tf->far, tf->elr, tf->spsr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
#include <machine/metalasm.h>
|
#include <machine/metalasm.h>
|
||||||
|
|
||||||
|
#define MRT_KENTER_IDX (7)
|
||||||
|
#define MRT_KEXIT_IDX (8)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Trap Handlers
|
* Trap Handlers
|
||||||
*/
|
*/
|
||||||
@ -191,21 +195,36 @@
|
|||||||
// daif bits are stored in PSTATE and are automatically re-enabled by eret
|
// daif bits are stored in PSTATE and are automatically re-enabled by eret
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
.global Trap_Pop
|
||||||
|
.text
|
||||||
|
Trap_Pop:
|
||||||
|
mov sp, x0
|
||||||
|
trapframe_restore_common
|
||||||
|
MENTER_GAS(MRT_KEXIT_IDX)
|
||||||
|
eret
|
||||||
|
|
||||||
.extern trap_entry
|
.extern trap_entry
|
||||||
.text
|
.text
|
||||||
|
|
||||||
interrupt_locore_entry:
|
interrupt_locore_entry:
|
||||||
|
MENTER_GAS(MRT_KENTER_IDX)
|
||||||
trapframe_save_common 1
|
trapframe_save_common 1
|
||||||
mov x0, sp
|
mov x0, sp
|
||||||
|
// pcpu for this core
|
||||||
|
mrs x18, tpidr_el1
|
||||||
bl trap_entry
|
bl trap_entry
|
||||||
trapframe_restore_common
|
trapframe_restore_common
|
||||||
|
MENTER_GAS(MRT_KEXIT_IDX)
|
||||||
eret
|
eret
|
||||||
|
|
||||||
exception_locore_entry:
|
exception_locore_entry:
|
||||||
|
MENTER_GAS(MRT_KENTER_IDX)
|
||||||
trapframe_save_common 0
|
trapframe_save_common 0
|
||||||
mov x0, sp
|
mov x0, sp
|
||||||
|
// pcpu for this core
|
||||||
|
mrs x18, tpidr_el1
|
||||||
bl trap_entry
|
bl trap_entry
|
||||||
trapframe_restore_common
|
trapframe_restore_common
|
||||||
|
MENTER_GAS(MRT_KEXIT_IDX)
|
||||||
eret
|
eret
|
||||||
|
|
||||||
.global _evt
|
.global _evt
|
||||||
|
@ -92,6 +92,8 @@ typedef struct Process {
|
|||||||
HandleQueue handles[PROCESS_HANDLE_SLOTS];
|
HandleQueue handles[PROCESS_HANDLE_SLOTS];
|
||||||
} Process;
|
} Process;
|
||||||
|
|
||||||
|
typedef void (*kthread_entry)(void *);
|
||||||
|
|
||||||
// General
|
// General
|
||||||
void Thread_Init();
|
void Thread_Init();
|
||||||
void Thread_InitAP();
|
void Thread_InitAP();
|
||||||
@ -107,7 +109,7 @@ uint64_t Process_Wait(Process *proc, uint64_t pid);
|
|||||||
|
|
||||||
// Thread functions
|
// Thread functions
|
||||||
Thread *Thread_Create(Process *proc);
|
Thread *Thread_Create(Process *proc);
|
||||||
Thread *Thread_KThreadCreate(void (*f)(void*), void *arg);
|
Thread *Thread_KThreadCreate(kthread_entry f, void *arg);
|
||||||
Thread *Thread_UThreadCreate(Thread *oldThr, uint64_t rip, uint64_t arg);
|
Thread *Thread_UThreadCreate(Thread *oldThr, uint64_t rip, uint64_t arg);
|
||||||
Thread *Thread_Lookup(Process *proc, uint64_t tid);
|
Thread *Thread_Lookup(Process *proc, uint64_t tid);
|
||||||
void Thread_Retain(Thread *thr);
|
void Thread_Retain(Thread *thr);
|
||||||
@ -127,7 +129,7 @@ void Thread_Dump(Thread *thr);
|
|||||||
|
|
||||||
// Platform functions
|
// Platform functions
|
||||||
void Thread_InitArch(Thread *thr);
|
void Thread_InitArch(Thread *thr);
|
||||||
void Thread_SetupKThread(Thread *thr, void (*f)(void *),
|
void Thread_SetupKThread(Thread *thr, kthread_entry f,
|
||||||
uintptr_t arg1, uintptr_t arg2, uintptr_t arg3);
|
uintptr_t arg1, uintptr_t arg2, uintptr_t arg3);
|
||||||
void Thread_SetupUThread(Thread *thr, uint64_t rip, uint64_t arg);
|
void Thread_SetupUThread(Thread *thr, uint64_t rip, uint64_t arg);
|
||||||
void Thread_SwitchArch(Thread *oldthr, Thread *newthr);
|
void Thread_SwitchArch(Thread *oldthr, Thread *newthr);
|
||||||
|
@ -238,7 +238,6 @@ Loader_LoadInit()
|
|||||||
*/
|
*/
|
||||||
PMap_LoadAS(thr->space); // Reload CR3
|
PMap_LoadAS(thr->space); // Reload CR3
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
/*
|
/*
|
||||||
* Pass in zero arguments with null pointers to init
|
* Pass in zero arguments with null pointers to init
|
||||||
*/
|
*/
|
||||||
@ -246,8 +245,9 @@ Loader_LoadInit()
|
|||||||
ap[0] = 0;
|
ap[0] = 0;
|
||||||
ap[1] = 0;
|
ap[1] = 0;
|
||||||
ap[2] = 0xDEADBEEF;
|
ap[2] = 0xDEADBEEF;
|
||||||
uintptr_t rsp = MEM_USERSPACE_STKTOP - PGSIZE;
|
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
uintptr_t rsp = MEM_USERSPACE_STKTOP - PGSIZE;
|
||||||
Copy_Out(&ap[0], rsp, sizeof(uintptr_t)*3);
|
Copy_Out(&ap[0], rsp, sizeof(uintptr_t)*3);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -265,7 +265,19 @@ Loader_LoadInit()
|
|||||||
tf.rdi = rsp;
|
tf.rdi = rsp;
|
||||||
Trap_Pop(&tf);
|
Trap_Pop(&tf);
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
NOT_IMPLEMENTED();
|
/*
|
||||||
|
* Pass in zero arguments with null pointers to init
|
||||||
|
*/
|
||||||
|
const vaddr_t sp = MEM_USERSPACE_STKTOP - PGSIZE;
|
||||||
|
|
||||||
|
Copy_Out(&ap[0], sp, sizeof(uintptr_t)*3);
|
||||||
|
|
||||||
|
TrapFrame tf;
|
||||||
|
memset(&tf, 0, sizeof(tf));
|
||||||
|
tf.elr = thr->proc->entrypoint;
|
||||||
|
tf.r0 = sp;
|
||||||
|
|
||||||
|
//Trap_Pop(&tf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -214,6 +214,7 @@ Sched_Scheduler()
|
|||||||
curProc[CPU()] = next;
|
curProc[CPU()] = next;
|
||||||
next->schedState = SCHED_STATE_RUNNING;
|
next->schedState = SCHED_STATE_RUNNING;
|
||||||
next->ctxSwitches++;
|
next->ctxSwitches++;
|
||||||
|
kprintf("sched: cur = %lu next = %lu\n", prev->tid, next->tid);
|
||||||
|
|
||||||
if (prev->schedState == SCHED_STATE_RUNNING) {
|
if (prev->schedState == SCHED_STATE_RUNNING) {
|
||||||
prev->schedState = SCHED_STATE_RUNNABLE;
|
prev->schedState = SCHED_STATE_RUNNABLE;
|
||||||
|
@ -141,7 +141,7 @@ Thread_Create(Process *proc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Thread *
|
Thread *
|
||||||
Thread_KThreadCreate(void (*f)(void *), void *arg)
|
Thread_KThreadCreate(kthread_entry f, void *arg)
|
||||||
{
|
{
|
||||||
Thread *thr = Thread_Create(kernelProcess);
|
Thread *thr = Thread_Create(kernelProcess);
|
||||||
if (!thr)
|
if (!thr)
|
||||||
|
Loading…
Reference in New Issue
Block a user