X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/92f6e64a6da763c45ff9f4ab5eafcab3d8766dcb..b60166b327a9108b07e3069fa6568a451529ffd9:/lunaix-os/arch/i386/pcontext.c diff --git a/lunaix-os/arch/i386/pcontext.c b/lunaix-os/arch/i386/pcontext.c new file mode 100644 index 0000000..a0ff6a6 --- /dev/null +++ b/lunaix-os/arch/i386/pcontext.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +#include +#include + +volatile struct x86_tss _tss = { .link = 0, + .esp0 = 0, + .ss0 = KDATA_SEG }; + +bool +inject_transfer_context(ptr_t vm_mnt, struct transfer_context* tctx) +{ + v_mapping mapping; + if (!vmm_lookupat(vm_mnt, tctx->inject, &mapping)) { + return false; + } + + vmm_mount_pg(PG_MOUNT_4, mapping.pa); + + ptr_t mount_inject = PG_MOUNT_4 + PG_OFFSET(tctx->inject); + memcpy((void*)mount_inject, &tctx->transfer, sizeof(tctx->transfer)); + + vmm_unmount_pg(PG_MOUNT_4); + return true; +} + +void +thread_setup_trasnfer(struct transfer_context* tctx, + ptr_t kstack_tp, ptr_t ustack_pt, + ptr_t entry, bool to_user) +{ + ptr_t offset = (ptr_t)&tctx->transfer.eret - (ptr_t)&tctx->transfer; + tctx->inject = align_stack(kstack_tp - sizeof(tctx->transfer)); + + tctx->transfer.isr = (isr_param){ + .registers = { + .ds = KDATA_SEG, + .es = KDATA_SEG, + .fs = KDATA_SEG, + .gs = KDATA_SEG + }, + .execp = (struct exec_param*)(tctx->inject + offset) + }; + + int code_seg = KCODE_SEG, data_seg = KDATA_SEG; + int mstate = cpu_ldstate(); + if (to_user) { + code_seg = UCODE_SEG, data_seg = UDATA_SEG; + mstate |= 0x200; // enable interrupt + } + + tctx->transfer.eret = (struct exec_param) { + .cs = code_seg, .eip = entry, + .ss = data_seg, .esp = align_stack(ustack_pt), + .eflags = mstate + }; +} \ No newline at end of file