Project: OSMain asm { USE64 IRQ_VECTORS:: //IDTInit() uses this table //for the initial vectors. //Other handlers are set, later, //with SetIDTEntry(). //See SetIDTEntry Grep DU4 IRQ00,IRQ01,IRQ02,IRQ03; DU4 IRQ04,IRQ05,IRQ06,IRQ07; DU4 IRQ08,IRQ09,IRQ0A,IRQ0B; DU4 IRQ0C,IRQ0D,IRQ0E,IRQ0F; DU4 IRQ10,IRQ11,IRQ12,IRQ13; DU4 IRQ14,IRQ15,IRQ16,IRQ17; DU4 IRQ18,IRQ19,IRQ1A,IRQ1B; DU4 IRQ1C,IRQ1D,IRQ1E,IRQ1F; DU4 IRQ20,IRQ21,IRQ22,IRQ23; DU4 IRQ24,IRQ25,IRQ26,IRQ27; DU4 IRQ28,IRQ29,IRQ2A,IRQ2B; DU4 IRQ2C,IRQ2D,IRQ2E,IRQ2F; DU4 IRQ30,IRQ31,IRQ32,IRQ33; DU4 IRQ34; //Set MAX_INITIAL_IDT if you add more // ************************************ COUT_PUT_F8: PUSH_C_REGS PUSH U8 8[RBP] CALL _PUT_FLOAT ADD RSP,8 POP_C_REGS COUT_RETURN: RET COUT_PUT_STR: PUSH RSI MOV RSI,RAX CALL PUT_STR POP RSI RET COUT_JMP_TABLE: DU8 PUT_HEX_U4; DU8 PUT_HEX_U4; DU8 PUT_HEX_U1; DU8 PUT_HEX_U1; DU8 PUT_HEX_U2; DU8 PUT_HEX_U2; DU8 PUT_HEX_U4; DU8 PUT_HEX_U4; DU8 PUT_HEX_U8; DU8 PUT_HEX_U8; DU8 COUT_PUT_F8; DU8 COUT_PUT_F8; //ptr types DU8 PUT_HEX_U4; DU8 PUT_HEX_U4; DU8 COUT_PUT_STR; DU8 COUT_PUT_STR; COUT_JOIN:: OR RBX,RBX JZ @@100 @@20: MOV RDX,U8 [RBP] MOV RAX,U8 8[RBP] CMP RDX,IT_U1+IT_NUM_IT JBE @@21 MOV RDX,IT_U8 @@21: CALL U8 COUT_JMP_TABLE[RDX*8] SUB RBP,16 DEC RBX JNZ @@20 @@100: RET IRQ30: JMP I4 _MP_CRASH //I_COUT //See PrsCout IRQ31:: PUSH RBP MOV RBP,RSP BT U8 24[RBP],RFLAGS_INTERRUPTS JNC @@I31 STI @@I31: MOV RBP,U8 32[RBP] MOV RBX,RAX //GET ARG CNT ADD RBX,RBX LEA RBP,-16[RBP+RBX*8] MOV RBX,RAX //GET ARG CNT CALL COUT_JOIN POP RBP IRET //I_COUTLN IRQ32:: PUSH RBP MOV RBP,RSP BT U8 24[RBP],RFLAGS_INTERRUPTS JNC @@I32 STI @@I32: MOV RBP,U8 32[RBP] MOV RBX,RAX //GET ARG CNT ADD RBX,RBX LEA RBP,-16[RBP+RBX*8] MOV RBX,RAX //GET ARG CNT CALL COUT_JOIN PUSH RAX MOV RAX,CH_CR CALL PUT_CHAR MOV RAX,CH_LINE_FEED CALL PUT_CHAR POP RAX POP RBP IRET //I_HIBERNATE IRQ33: PUSH RAX XOR RAX,RAX MOV EAX,U4 LAPIC_EOI MOV U4 [RAX],0 XOR RAX,RAX LOCK BTS U4 GS:CPU_CPU_FLAGS[RAX],CPUf_HIBERNATING STI HLT LOCK BTR U4 GS:CPU_CPU_FLAGS[RAX],CPUf_HIBERNATING POP RAX IRET //I_WAKE IRQ34: PUSH RAX XOR RAX,RAX MOV EAX,U4 LAPIC_EOI MOV U4 [RAX],0 POP RAX IRET //I_TIMER IRQ20: CALL SAVE_CONTEXT //PREEMPTIVE CLD MOV RBP,RSP MOV RBX,U8 [RBP] MOV U8 TASK_RIP[RSI],RBX MOV RAX,U8 16[RBP] MOV U8 TASK_RFLAGS[RSI],RAX MOV RAX,U8 24[RBP] MOV U8 TASK_RSP[RSI],RAX XOR RAX,RAX MOV RDI,U8 GS:CPU_ADDRESS[RAX] LOCK INC U8 CPU_TOTAL_JIFFIES[RDI] BT U8 TASK_TASK_FLAGS[RSI],TASKf_IDLE JC @@1a CMP RBX,U4 IDLE_START JB @@1 CMP RBX,U4 IDLE_END JA @@1 @@1a: LOCK INC U8 CPU_IDLE_POINT_HITS[RDI] @@1: MOV RAX,U8 CPU_TIMER_IRQ_CHAIN[RDI] OR RAX,RAX JZ @@2 PUSH RSI CALL RAX ADD RSP,8 CLI @@2: MOV RAX,U8 CPU_NUM[RDI] OR RAX,RAX JZ @@3 XOR RAX,RAX MOV EAX,U4 LAPIC_EOI MOV U4 [RAX],0 JMP @@5 @@3: MOV AL,0x20 //ACKNOWLEDGE INTERRUPT OUT 0x20,AL @@5: MOV RAX,SYS_SEMAS BT U4 SYS_SEMA_SINGLE_USER*SEMA_STRUCT_SIZE[RAX],0 JC @@5C BT U8 TASK_TASK_FLAGS[RSI],TASKf_PREEMPT JC I4 RESTORE_NEXT_RSI_TASK @@5C: LOCK BTR U8 TASK_TASK_FLAGS[RSI],TASKf_HAS_BEEN_SWAPPED JC @@5B LOCK INC U8 CPU_NO_PREEMPT_HITS[RDI] @@5B: JMP I4 RESTORE_RSI_NO_PREEMPT_TASK IRQ00:: PUSH 0 JMP IRQFAULT_JMP IRQ01: PUSH 1 JMP IRQFAULT_JMP //NMI IRQ02: HLT JMP IRQ02 IRQ03: PUSH 3 JMP IRQFAULT_JMP IRQ04: PUSH 4 JMP IRQFAULT_JMP IRQ05: PUSH 5 JMP IRQFAULT_JMP IRQ06: PUSH 6 JMP IRQFAULT_JMP IRQ07: PUSH 7 JMP IRQFAULT_JMP IRQ08: PUSH 8 JMP IRQFAULT_JMP IRQ09: PUSH 9 JMP IRQFAULT_JMP IRQ0A: PUSH 0x0A JMP IRQFAULT_JMP IRQ0B: PUSH 0x0B JMP IRQFAULT_JMP IRQ0C: PUSH 0x0C JMP IRQFAULT_JMP IRQ0D: PUSH 0x0D JMP IRQFAULT_JMP IRQ0E: PUSH 0x0E JMP IRQFAULT_JMP IRQ0F: PUSH 0x0F JMP IRQFAULT_JMP IRQ10: PUSH 0x10 IRQFAULT_JMP: JMP IRQFAULT IRQ11: PUSH 0x11 JMP IRQFAULT IRQ12: PUSH 0x12 JMP IRQFAULT IRQ13: PUSH 0x13 JMP IRQFAULT IRQ14: PUSH 0x14 JMP IRQFAULT IRQ15: PUSH 0x15 JMP IRQFAULT IRQ16: PUSH 0x16 JMP IRQFAULT IRQ17: PUSH 0x17 JMP IRQFAULT IRQ18: PUSH 0x18 JMP IRQFAULT IRQ19: PUSH 0x19 JMP IRQFAULT IRQ1A: PUSH 0x1A JMP IRQFAULT IRQ1B: PUSH 0x1B JMP IRQFAULT IRQ1C: PUSH 0x1C JMP IRQFAULT IRQ1D: PUSH 0x1D JMP IRQFAULT IRQ1E: PUSH 0x1E JMP IRQFAULT IRQ1F: PUSH 0x1F JMP IRQFAULT IRQ21: PUSH 0x21 JMP IRQFAULT IRQ22: PUSH 0x22 JMP IRQFAULT IRQ23: PUSH 0x23 JMP IRQFAULT IRQ24: PUSH 0x24 JMP IRQFAULT IRQ25: PUSH 0x25 JMP IRQFAULT IRQ26: PUSH 0x26 JMP IRQFAULT //This might be a spurious interrupt //TODO: Why is this needed? IRQ27: PUSH RAX MOV AL,0x20 OUT 0x20,AL POP RAX IRET IRQ28: PUSH 0x28 JMP IRQFAULT IRQ29: PUSH 0x29 JMP IRQFAULT IRQ2A: PUSH 0x2A JMP IRQFAULT IRQ2B: PUSH 0x2B JMP IRQFAULT IRQ2C: PUSH 0x2C JMP IRQFAULT IRQ2D: PUSH 0x2D JMP IRQFAULT IRQ2E: PUSH 0x2E JMP IRQFAULT IRQ2F: PUSH 0x2F JMP IRQFAULT // ************************************ IRQFAULT:: PUSH RBX MOV RBX,U8 8[RSP] PUSH RAX XOR RAX,RAX MOV FS:U4 TASK_FAULT_NUM[RAX],EBX POP RAX POP RBX ADD RSP,8 CALL SAVE_CONTEXT XOR RDX,RDX MOV U8 TASK_FAULT_ERR_CODE[RSI],RDX MOV EDX,U4 TASK_FAULT_NUM[RSI] BT U8 [FAULT_ERR_CODE_BITMAP],RDX JNC @@1 POP U8 TASK_FAULT_ERR_CODE[RSI] @@1: MOV RBP,RSP MOV RAX,U8 [RBP] MOV U8 TASK_RIP[RSI],RAX MOV RAX,U8 16[RBP] MOV U8 TASK_RFLAGS[RSI],RAX MOV RAX,U8 24[RBP] MOV U8 TASK_RSP[RSI],RAX MOV RSP,RAX MOV RBP,TASK_RBP[RSI] MOV RSI,TASK_RSI[RSI] CALL _FAULT2 //See _FAULT2 JMP I4 RESTORE_FS_TASK_WITH_KEY_CHECK FAULT_ERR_CODE_BITMAP:: DU4 0x00027D00; } asm {_INIT_IDT::} U0 IDTInit() { //interrupt descriptor table U8 i,temp_ptr[2]; U4 *src=IRQ_VECTORS,*dst; dst=Gs->idt=CAlloc(16*256); for (i=0;i<MAX_INITIAL_IDT;i++) { *dst><(U2 *)++=*src><(U2 *)++; *dst><(U2 *)++=SYS_CS64_SEL; *dst><(U2 *)++=0x8E00; //E=32-bit irq gate *dst><(U2 *)++=*src><(U2 *)++; *dst><(U8 *)++=0; } dst=temp_ptr; *dst><(U2 *)++=256*16-1; *dst><(U4 *)++=Gs->idt><(U8).u4[0]; *dst><(U4 *)++=Gs->idt><(U8).u4[1]; *dst><(U2 *)++=0; SetRAX(temp_ptr); asm { LIDT U8 [RAX] } } U0 *GetIDTEntry(U8 irq,U8 core_num) { U8 result,*src=cpu_structs[core_num].idt><(U1 *)+irq*16; result.u2[0]=*src><(U2 *); src><(U1 *)+=6; result.u2[1]=*src><(U2 *)++; result.u4[1]=*src><(U4 *); return result; } U0 *SetIDTEntry(U8 irq,U0 (*fp_new_handler)(),U8 core_num) { //See ::/LT/Doc/Lectures/Interrupts.CPZ //See ::/LT/Demo/MultiCore/Interrupts.CPZ U8 result=GetIDTEntry(irq,core_num); U1 *dst=cpu_structs[core_num].idt><(U1 *)+irq*16; *dst><(U2 *)++=fp_new_handler><(U8).u2[0]; *dst><(U2 *)++=SYS_CS64_SEL; *dst><(U2 *)++=0x8E00; //E=32-bit irq gate *dst><(U2 *)++=fp_new_handler><(U8).u2[1]; *dst><(U4 *)++=fp_new_handler><(U8).u4[1]; *dst><(U4 *)++=0; return result; }