X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/6c506d8916fb114675e93d0e2cb20831d4022294..d1b1c8d9119229dbeed06cd252917e54a1cb77f6:/lunaix-os/arch/i386/hart.c?ds=inline diff --git a/lunaix-os/arch/i386/hart.c b/lunaix-os/arch/i386/hart.c new file mode 100644 index 0000000..09bd2b3 --- /dev/null +++ b/lunaix-os/arch/i386/hart.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +#include +#include + +volatile struct x86_tss _tss = { .link = 0, + .esp0 = 0, + .ss0 = KDATA_SEG }; + +bool +install_hart_transition(ptr_t vm_mnt, struct hart_transition* ht) +{ + pte_t pte; + if (!vmm_lookupat(vm_mnt, ht->inject, &pte)) { + return false; + } + + mount_page(PG_MOUNT_4, pte_paddr(pte)); + + ptr_t mount_inject = PG_MOUNT_4 + va_offset(ht->inject); + memcpy((void*)mount_inject, &ht->transfer, sizeof(ht->transfer)); + + unmount_page(PG_MOUNT_4); + return true; +} + +void +hart_prepare_transition(struct hart_transition* ht, + ptr_t kstack_tp, ptr_t ustack_pt, + ptr_t entry, bool to_user) +{ + ptr_t offset = (ptr_t)&ht->transfer.eret - (ptr_t)&ht->transfer; + ht->inject = align_stack(kstack_tp - sizeof(ht->transfer)); + + ht->transfer.state = (struct hart_state){ + .registers = { + .ds = KDATA_SEG, + .es = KDATA_SEG, + .fs = KDATA_SEG, + .gs = KDATA_SEG + }, + .execp = (struct exec_param*)(ht->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 + } + + ht->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