1*110f0d93SGleb Natapov #include "libcflat.h" 2*110f0d93SGleb Natapov #include "isr.h" 3*110f0d93SGleb Natapov #include "vm.h" 4*110f0d93SGleb Natapov #include "desc.h" 5*110f0d93SGleb Natapov 6*110f0d93SGleb Natapov #ifdef __x86_64__ 7*110f0d93SGleb Natapov # define R "r" 8*110f0d93SGleb Natapov #else 9*110f0d93SGleb Natapov # define R "e" 10*110f0d93SGleb Natapov #endif 11*110f0d93SGleb Natapov 12*110f0d93SGleb Natapov extern char isr_entry_point[]; 13*110f0d93SGleb Natapov 14*110f0d93SGleb Natapov asm ( 15*110f0d93SGleb Natapov "isr_entry_point: \n" 16*110f0d93SGleb Natapov #ifdef __x86_64__ 17*110f0d93SGleb Natapov "push %r15 \n\t" 18*110f0d93SGleb Natapov "push %r14 \n\t" 19*110f0d93SGleb Natapov "push %r13 \n\t" 20*110f0d93SGleb Natapov "push %r12 \n\t" 21*110f0d93SGleb Natapov "push %r11 \n\t" 22*110f0d93SGleb Natapov "push %r10 \n\t" 23*110f0d93SGleb Natapov "push %r9 \n\t" 24*110f0d93SGleb Natapov "push %r8 \n\t" 25*110f0d93SGleb Natapov #endif 26*110f0d93SGleb Natapov "push %"R "di \n\t" 27*110f0d93SGleb Natapov "push %"R "si \n\t" 28*110f0d93SGleb Natapov "push %"R "bp \n\t" 29*110f0d93SGleb Natapov "push %"R "sp \n\t" 30*110f0d93SGleb Natapov "push %"R "bx \n\t" 31*110f0d93SGleb Natapov "push %"R "dx \n\t" 32*110f0d93SGleb Natapov "push %"R "cx \n\t" 33*110f0d93SGleb Natapov "push %"R "ax \n\t" 34*110f0d93SGleb Natapov #ifdef __x86_64__ 35*110f0d93SGleb Natapov "mov %rsp, %rdi \n\t" 36*110f0d93SGleb Natapov "callq *8*16(%rsp) \n\t" 37*110f0d93SGleb Natapov #else 38*110f0d93SGleb Natapov "push %esp \n\t" 39*110f0d93SGleb Natapov "calll *4+4*8(%esp) \n\t" 40*110f0d93SGleb Natapov "add $4, %esp \n\t" 41*110f0d93SGleb Natapov #endif 42*110f0d93SGleb Natapov "pop %"R "ax \n\t" 43*110f0d93SGleb Natapov "pop %"R "cx \n\t" 44*110f0d93SGleb Natapov "pop %"R "dx \n\t" 45*110f0d93SGleb Natapov "pop %"R "bx \n\t" 46*110f0d93SGleb Natapov "pop %"R "bp \n\t" 47*110f0d93SGleb Natapov "pop %"R "bp \n\t" 48*110f0d93SGleb Natapov "pop %"R "si \n\t" 49*110f0d93SGleb Natapov "pop %"R "di \n\t" 50*110f0d93SGleb Natapov #ifdef __x86_64__ 51*110f0d93SGleb Natapov "pop %r8 \n\t" 52*110f0d93SGleb Natapov "pop %r9 \n\t" 53*110f0d93SGleb Natapov "pop %r10 \n\t" 54*110f0d93SGleb Natapov "pop %r11 \n\t" 55*110f0d93SGleb Natapov "pop %r12 \n\t" 56*110f0d93SGleb Natapov "pop %r13 \n\t" 57*110f0d93SGleb Natapov "pop %r14 \n\t" 58*110f0d93SGleb Natapov "pop %r15 \n\t" 59*110f0d93SGleb Natapov #endif 60*110f0d93SGleb Natapov ".globl isr_iret_ip\n\t" 61*110f0d93SGleb Natapov #ifdef __x86_64__ 62*110f0d93SGleb Natapov "add $8, %rsp \n\t" 63*110f0d93SGleb Natapov "isr_iret_ip: \n\t" 64*110f0d93SGleb Natapov "iretq \n\t" 65*110f0d93SGleb Natapov #else 66*110f0d93SGleb Natapov "add $4, %esp \n\t" 67*110f0d93SGleb Natapov "isr_iret_ip: \n\t" 68*110f0d93SGleb Natapov "iretl \n\t" 69*110f0d93SGleb Natapov #endif 70*110f0d93SGleb Natapov ); 71*110f0d93SGleb Natapov 72*110f0d93SGleb Natapov void handle_irq(unsigned vec, void (*func)(isr_regs_t *regs)) 73*110f0d93SGleb Natapov { 74*110f0d93SGleb Natapov u8 *thunk = vmalloc(50); 75*110f0d93SGleb Natapov 76*110f0d93SGleb Natapov set_idt_entry(vec, thunk, 0); 77*110f0d93SGleb Natapov 78*110f0d93SGleb Natapov #ifdef __x86_64__ 79*110f0d93SGleb Natapov /* sub $8, %rsp */ 80*110f0d93SGleb Natapov *thunk++ = 0x48; *thunk++ = 0x83; *thunk++ = 0xec; *thunk++ = 0x08; 81*110f0d93SGleb Natapov /* mov $func_low, %(rsp) */ 82*110f0d93SGleb Natapov *thunk++ = 0xc7; *thunk++ = 0x04; *thunk++ = 0x24; 83*110f0d93SGleb Natapov *(u32 *)thunk = (ulong)func; thunk += 4; 84*110f0d93SGleb Natapov /* mov $func_high, %(rsp+4) */ 85*110f0d93SGleb Natapov *thunk++ = 0xc7; *thunk++ = 0x44; *thunk++ = 0x24; *thunk++ = 0x04; 86*110f0d93SGleb Natapov *(u32 *)thunk = (ulong)func >> 32; thunk += 4; 87*110f0d93SGleb Natapov /* jmp isr_entry_point */ 88*110f0d93SGleb Natapov *thunk ++ = 0xe9; 89*110f0d93SGleb Natapov *(u32 *)thunk = (ulong)isr_entry_point - (ulong)(thunk + 4); 90*110f0d93SGleb Natapov #else 91*110f0d93SGleb Natapov /* push $func */ 92*110f0d93SGleb Natapov *thunk++ = 0x68; 93*110f0d93SGleb Natapov *(u32 *)thunk = (ulong)func; thunk += 4; 94*110f0d93SGleb Natapov /* jmp isr_entry_point */ 95*110f0d93SGleb Natapov *thunk++ = 0xe9; 96*110f0d93SGleb Natapov *(u32 *)thunk = (ulong)isr_entry_point - (ulong)(thunk + 4); 97*110f0d93SGleb Natapov #endif 98*110f0d93SGleb Natapov } 99