A Total Overhaul on the Lunaix's Virtual Memory Model (#26)
[lunaix-os.git] / lunaix-os / arch / i386 / pcontext.c
1 #include <lunaix/process.h>
2 #include <lunaix/pcontext.h>
3 #include <lunaix/mm/vmm.h>
4 #include <klibc/string.h>
5
6 #include <sys/mm/mempart.h>
7 #include <sys/abi.h>
8
9 volatile struct x86_tss _tss = { .link = 0,
10                                  .esp0 = 0,
11                                  .ss0 = KDATA_SEG };
12
13 bool
14 inject_transfer_context(ptr_t vm_mnt, struct transfer_context* tctx)
15 {
16     pte_t pte;
17     if (!vmm_lookupat(vm_mnt, tctx->inject, &pte)) {
18         return false;
19     }
20
21     mount_page(PG_MOUNT_4, pte_paddr(pte));
22
23     ptr_t mount_inject = PG_MOUNT_4 + va_offset(tctx->inject);
24     memcpy((void*)mount_inject, &tctx->transfer, sizeof(tctx->transfer));
25     
26     unmount_page(PG_MOUNT_4);
27     return true;
28 }
29
30 void
31 thread_setup_trasnfer(struct transfer_context* tctx, 
32                       ptr_t kstack_tp, ptr_t ustack_pt, 
33                       ptr_t entry, bool to_user) 
34 {
35     ptr_t offset = (ptr_t)&tctx->transfer.eret - (ptr_t)&tctx->transfer;
36     tctx->inject = align_stack(kstack_tp - sizeof(tctx->transfer));
37
38     tctx->transfer.isr = (isr_param){ 
39                             .registers = { 
40                                 .ds = KDATA_SEG,
41                                 .es = KDATA_SEG,
42                                 .fs = KDATA_SEG,
43                                 .gs = KDATA_SEG 
44                             },
45                             .execp = (struct exec_param*)(tctx->inject + offset)
46                         };
47     
48     int code_seg = KCODE_SEG, data_seg = KDATA_SEG;
49     int mstate = cpu_ldstate();
50     if (to_user) {
51         code_seg = UCODE_SEG, data_seg = UDATA_SEG;
52         mstate |= 0x200;   // enable interrupt
53     }
54
55     tctx->transfer.eret = (struct exec_param) {
56                             .cs = code_seg, .eip = entry, 
57                             .ss = data_seg, .esp = align_stack(ustack_pt),
58                             .eflags = mstate
59                         };
60 }