/*init functions makes me happy*/ void local_bsp_apic_init(void) { uint32_t v; kprintf("[LW] Checking APIC is present ... "); if(__local_apic_check()<0) { kprintf("FAIL\n"); return; } else kprintf("OK\n"); v=local_apic->version.version; kprintf("[LW] APIC version: %d\n",v); /* first we're need to clear APIC to avoid magical results */ __local_apic_clear(); /* enable APIC */ __enable_apic(); /* enable wire mode*/ /* set nil vectors */ __set_lvt_lint_vector(0,0x0); __set_lvt_lint_vector(1,0x0); /*set mode#7 for lint0*/ local_apic->lvt_lint0.tx_mode=0x7; /*set mode#4 for lint1*/ local_apic->lvt_lint1.tx_mode=0x4; /*tx_mode & polarity set to 0 on both lintx*/ local_apic->lvt_lint0.tx_status |= (1 << 0); local_apic->lvt_lint0.polarity |= (1 << 0); local_apic->lvt_lint1.tx_status |= (1 << 0); local_apic->lvt_lint1.polarity |= (1 << 0); }
static int __local_apic_init(bool msgout) { uint32_t v; int i=0,l; apic_lvt_lint_t lvt_lint; apic_icr1_t icr1; if (msgout) { kprintf("APIC: Checking APIC is present ... "); if(__local_apic_check()<0) { kprintf("FAIL\n"); return -1; } else{ kprintf("OK\n"); } } enable_l_apic_in_msr(); v=get_apic_version(); if (msgout) kprintf("APIC: APIC version: %d apic id:%x\n",v,get_local_apic_id()); /* first we're need to clear APIC to avoid magical results */ __local_apic_clear(); __disable_apic(); set_apic_dfr_mode(0xf); kprintf(" APIC id:%d destination id :%d \n",get_local_apic_id(),(1 << (__apics_number & 7))); set_apic_ldr_logdest(1 << (__apics_number & 7)); __apics_number++; apic_set_task_priority(0); /* clear bits for interrupts - can be filled up to other os */ for(i=7;i>=0;i--){ v=local_apic->isr[i].bits; for(l=31;l>=0;l--) if(v & (1 << l)) local_apic_send_eoi(); } set_apic_spurious_vector(0xff); __enable_apic(); /* set nil vectors */ __set_lvt_lint_vector(0,0x34); __set_lvt_lint_vector(1,0x35); /*set mode#7 extINT for lint0*/ lvt_lint=local_apic->lvt_lint0; lvt_lint.tx_mode=0x7; lvt_lint.mask=1; lvt_lint.tx_status = 0x0; lvt_lint.polarity = LEVEL_DEASSERT; lvt_lint.trigger = TRIG_EDGE; local_apic->lvt_lint0.reg=lvt_lint.reg; /*set mode#4 NMI for lint1*/ lvt_lint=local_apic->lvt_lint1; lvt_lint.tx_mode=0x4; lvt_lint.mask=1; lvt_lint.tx_status = 0x0; lvt_lint.polarity = LEVEL_DEASSERT; lvt_lint.trigger = TRIG_EDGE; local_apic->lvt_lint1.reg=lvt_lint.reg; /* ok, now we're need to set esr vector to 0xfe */ local_apic->lvt_error.vector = 0xfe; /*enable to receive errors*/ if(__get_maxlvt()>3) local_apic->esr.tx_cs_err = 0x0; /* set icr1 registers*/ icr1=local_apic->icr1; icr1.tx_mode=TXMODE_INIT; icr1.rx_mode=DMODE_PHY; icr1.level=0x0; icr1.shorthand=0x2; icr1.trigger=0x1; local_apic->icr1.reg=icr1.reg; // set internal apic error interrupt vector *(uint32_t*)((uint64_t)local_apic + 0x370) = 200; return 0; }