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