hschumann2/TempleOS-Source-Code
0838
1 2asm {3INT_MP_CRASH_ADDR:: //Forward reference to work around compiler4 DU32 &IntMPCrash;5 6INT_WAKE::7 PUSH RDX8 PUSH RAX9 MOV EAX,&dev10 MOV EDX,U32 LAPIC_EOI11 MOV RAX,U64 CDevGlbls.uncached_alias[RAX]12 MOV U32 [RAX+RDX],013 POP RAX14 POP RDX15 IRET16 17IRQ_TIMER:: //I_TIMER18 CALL TASK_CONTEXT_SAVE19 CLD20 21 MOV RAX,U64 [RSP]22 MOV U64 CTask.rip[RSI],RAX23 MOV RAX,U64 16[RSP]24 MOV U64 CTask.rflags[RSI],RAX25 MOV RAX,U64 24[RSP]26 MOV U64 CTask.rsp[RSI],RAX27 28 XOR RAX,RAX29 MOV RDI,U64 GS:CCPU.addr[RAX]30 LOCK31 INC U64 CCPU.total_jiffies[RDI]32 33 BT U64 CTask.task_flags[RSI],TASKf_IDLE34 JNC @@0535 LOCK36 INC U64 CCPU.idle_pt_hits[RDI]37 38@@05: MOV RAX,U64 CCPU.profiler_timer_irq[RDI]39 TEST RAX,RAX40 JZ @@1041 PUSH RSI42 CALL RAX //See ProfTimerInt().43 JMP @@1544@@10: ADD RSP,845@@15: CLI46 MOV RAX,U64 CCPU.num[RDI]47 TEST RAX,RAX48 JZ @@2049 50 MOV EAX,&dev51 MOV EDX,U32 LAPIC_EOI52 MOV RAX,U64 CDevGlbls.uncached_alias[RAX]53 MOV U32 [RAX+RDX],054 JMP @@2555 56@@20: CALL &IntCore0TimerHndlr //Only Core 0 calls this.57@@25: XOR RAX,RAX58 CMP RSI,U64 GS:CCPU.idle_task[RAX]59 JE I32 RESTORE_SETH_TASK_IF_READY60 JMP I32 RESTORE_RSI_TASK61//************************************62INT_FAULT::63 PUSH RBX64 PUSH RAX65 MOV BL,U8 16[RSP] //We pushed fault_num IntFaultHndlrsNew().66 XOR RAX,RAX67 MOV FS:U8 CTask.fault_num[RAX],BL68 POP RAX69 POP RBX70 ADD RSP,8 //Pop fault_num71 72 CALL TASK_CONTEXT_SAVE73 74 XOR RDX,RDX75 MOV U64 CTask.fault_err_code[RSI],RDX76 MOV EDX,U32 CTask.fault_num[RSI]77 BT U64 [INT_FAULT_ERR_CODE_BITMAP],RDX78 JNC @@179 POP U64 CTask.fault_err_code[RSI]80 81@@1: MOV RAX,U64 [RSP]82 MOV U64 CTask.rip[RSI],RAX83 MOV RAX,U64 16[RSP]84 MOV U64 CTask.rflags[RSI],RAX85 MOV RSP,U64 24[RSP]86 MOV U64 CTask.rsp[RSI],RSP87 MOV RBP,CTask.rbp[RSI]88 PUSH U64 CTask.fault_err_code[RSI]89 PUSH U64 CTask.fault_num[RSI]90 MOV RSI,CTask.rsi[RSI]91 CALL &Fault2 //See Fault292 JMP I32 RESTORE_FS_TASK93 94INT_FAULT_ERR_CODE_BITMAP::95 DU32 0x00027D00,0,0,0,0,0,0,0;96}97 98U8 *IntEntryGet(I64 irq)99{//Get interrupt vector.100 U8 *res;101 I64 *src;102 src=dev.idt(U8 *)+irq*16;103 res(I64).u16[0]=*src(U16 *);104 src(U8 *)+=6;105 res(I64).u16[1]=*src(U16 *)++;106 res(I64).u32[1]=*src(U32 *);107 return res;108}109 110U8 *IntEntrySet(I64 irq,U0 (*fp_new_hndlr)(),I64 type=IDTET_IRQ,I64 dpl=0)111{//Set interrupt vector. See IDTET_IRQ.112//See ::/Demo/Lectures/InterruptDemo.HC.113 //See ::/Demo/MultiCore/Interrupts.HC.114 I64 fp=fp_new_hndlr;115 U8 *res,*dst;116 PUSHFD117 CLI118 res=IntEntryGet(irq);119 dst=dev.idt(U8 *)+irq*16;120 *dst(U16 *)++=fp.u16[0];121 *dst(U16 *)++=offset(CGDT.cs64);122 *dst(U16 *)++=0x8000+type<<8+dpl<<13;123 *dst(U16 *)++=fp.u16[1];124 *dst(U32 *)++=fp.u32[1];125 *dst(U32 *)=0;126 POPFD127 return res;128}129 130U0 IntsInit()131{//Init 8259132 OutU8(0x20,0x11); //IW1133 OutU8(0xA0,0x11); //IW1134 OutU8(0x21,0x20); //IW2135 OutU8(0xA1,0x28); //IW2136 OutU8(0x21,0x04); //IW3137 OutU8(0xA1,0x02); //IW3138 OutU8(0x21,0x0D); //IW4139 OutU8(0xA1,0x09); //IW4140 OutU8(0x21,0xFA); //Mask all but IRQ0 (timer) and IRQ2 Cascade.141 OutU8(0xA1,0xFF);142}143 144interrupt U0 IntNop()145{//Make unplanned IRQs stop by all means!146 OutU8(0xA0,0x20);147 OutU8(0x20,0x20);148 *(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;149}150 151interrupt U0 IntDivZero()152{153 if (Gs->num) {154 mp_cnt=1;155 dbg.mp_crash->cpu_num=Gs->num;156 dbg.mp_crash->task=Fs;157 MOV RAX,U64 8[RBP] //Get RIP off of stk.158 dbg.mp_crash->rip=GetRAX;159 dbg.mp_crash->msg="Div Zero";160 dbg.mp_crash->msg_num=0;161 MPInt(I_MP_CRASH,0);162 SysHlt;163 }164 throw('DivZero');165}166 167U8 *IntFaultHndlrsNew()168{169 I64 i;170 U8 *res=MAlloc(256*7,Fs->code_heap),*dst=res;171 for (i=0;i<256;i++) {172 *dst++=0x6A; //PUSH I8 xx173 *dst(I8 *)++=i;174 *dst++=0xE9; //JMP I32 xxxxxxxx175 *dst(I32 *)=INT_FAULT-dst-4;176 dst+=4;177 }178 return res;179}180 181U0 IntInit1()182{//Interrupt descriptor table part1.183 I64 i;184 CSysLimitBase tmp_ptr;185 if (!Gs->num) {//Gs cur CCPU struct186 dev.idt=CAlloc(16*256);187 for (i=0;i<256;i++)188 IntEntrySet(i,&IntNop);189 }190 tmp_ptr.limit=256*16-1;191 tmp_ptr.base =dev.idt;192 SetRAX(&tmp_ptr);193 LIDT U64 [RAX]194}195 196U0 IntInit2()197{//Interrupt descriptor table part2: Core 0 Only.198 I64 i;199 PUSHFD200 CLI201 IntEntrySet(I_DIV_ZERO,&IntDivZero);202 for (i=1;i<0x20;i++)203 IntEntrySet(i,&dbg.int_fault_code[7*i]);204/*In theory, we use the PIC mask reg to insure we don't get205anything but keyboard, mouse and timer IRQs. In practice, I've206gotten IRQ 0x27, perhaps because I didn't initialize the APIC.207I go ahead and ACK PIC in IntNop().208I have no idea why I got a IRQ 0x27.209*/210 IntEntrySet(I_NMI,_SYS_HLT);211 IntEntrySet(I_TIMER,IRQ_TIMER);212 IntEntrySet(I_MP_CRASH,*INT_MP_CRASH_ADDR(U32 *));213 IntEntrySet(I_WAKE,INT_WAKE);214 IntEntrySet(I_DBG,&dbg.int_fault_code[7*I_DBG]);215 POPFD216}217 