1*433d6423SLionel Sambuc #ifndef __APIC_H__ 2*433d6423SLionel Sambuc #define __APIC_H__ 3*433d6423SLionel Sambuc 4*433d6423SLionel Sambuc #define APIC_ENABLE 0x100 5*433d6423SLionel Sambuc #define APIC_FOCUS_DISABLED (1 << 9) 6*433d6423SLionel Sambuc #define APIC_SIV 0xFF 7*433d6423SLionel Sambuc 8*433d6423SLionel Sambuc #define APIC_TDCR_2 0x00 9*433d6423SLionel Sambuc #define APIC_TDCR_4 0x01 10*433d6423SLionel Sambuc #define APIC_TDCR_8 0x02 11*433d6423SLionel Sambuc #define APIC_TDCR_16 0x03 12*433d6423SLionel Sambuc #define APIC_TDCR_32 0x08 13*433d6423SLionel Sambuc #define APIC_TDCR_64 0x09 14*433d6423SLionel Sambuc #define APIC_TDCR_128 0x0a 15*433d6423SLionel Sambuc #define APIC_TDCR_1 0x0b 16*433d6423SLionel Sambuc 17*433d6423SLionel Sambuc #define APIC_LVTT_VECTOR_MASK 0x000000FF 18*433d6423SLionel Sambuc #define APIC_LVTT_DS_PENDING (1 << 12) 19*433d6423SLionel Sambuc #define APIC_LVTT_MASK (1 << 16) 20*433d6423SLionel Sambuc #define APIC_LVTT_TM (1 << 17) 21*433d6423SLionel Sambuc 22*433d6423SLionel Sambuc #define APIC_LVT_IIPP_MASK 0x00002000 23*433d6423SLionel Sambuc #define APIC_LVT_IIPP_AH 0x00002000 24*433d6423SLionel Sambuc #define APIC_LVT_IIPP_AL 0x00000000 25*433d6423SLionel Sambuc 26*433d6423SLionel Sambuc #define IOAPIC_REGSEL 0x0 27*433d6423SLionel Sambuc #define IOAPIC_RW 0x10 28*433d6423SLionel Sambuc 29*433d6423SLionel Sambuc #define APIC_ICR_DM_MASK 0x00000700 30*433d6423SLionel Sambuc #define APIC_ICR_VECTOR APIC_LVTT_VECTOR_MASK 31*433d6423SLionel Sambuc #define APIC_ICR_DM_FIXED (0 << 8) 32*433d6423SLionel Sambuc #define APIC_ICR_DM_LOWEST_PRIORITY (1 << 8) 33*433d6423SLionel Sambuc #define APIC_ICR_DM_SMI (2 << 8) 34*433d6423SLionel Sambuc #define APIC_ICR_DM_RESERVED (3 << 8) 35*433d6423SLionel Sambuc #define APIC_ICR_DM_NMI (4 << 8) 36*433d6423SLionel Sambuc #define APIC_ICR_DM_INIT (5 << 8) 37*433d6423SLionel Sambuc #define APIC_ICR_DM_STARTUP (6 << 8) 38*433d6423SLionel Sambuc #define APIC_ICR_DM_EXTINT (7 << 8) 39*433d6423SLionel Sambuc 40*433d6423SLionel Sambuc #define APIC_ICR_DM_PHYSICAL (0 << 11) 41*433d6423SLionel Sambuc #define APIC_ICR_DM_LOGICAL (1 << 11) 42*433d6423SLionel Sambuc 43*433d6423SLionel Sambuc #define APIC_ICR_DELIVERY_PENDING (1 << 12) 44*433d6423SLionel Sambuc 45*433d6423SLionel Sambuc #define APIC_ICR_INT_POLARITY (1 << 13) 46*433d6423SLionel Sambuc 47*433d6423SLionel Sambuc #define APIC_ICR_LEVEL_ASSERT (1 << 14) 48*433d6423SLionel Sambuc #define APIC_ICR_LEVEL_DEASSERT (0 << 14) 49*433d6423SLionel Sambuc 50*433d6423SLionel Sambuc #define APIC_ICR_TRIGGER (1 << 15) 51*433d6423SLionel Sambuc 52*433d6423SLionel Sambuc #define APIC_ICR_INT_MASK (1 << 16) 53*433d6423SLionel Sambuc 54*433d6423SLionel Sambuc #define APIC_ICR_DEST_FIELD (0 << 18) 55*433d6423SLionel Sambuc #define APIC_ICR_DEST_SELF (1 << 18) 56*433d6423SLionel Sambuc #define APIC_ICR_DEST_ALL (2 << 18) 57*433d6423SLionel Sambuc #define APIC_ICR_DEST_ALL_BUT_SELF (3 << 18) 58*433d6423SLionel Sambuc 59*433d6423SLionel Sambuc #define LOCAL_APIC_DEF_ADDR 0xfee00000 /* default local apic address */ 60*433d6423SLionel Sambuc #define IO_APIC_DEF_ADDR 0xfec00000 /* default i/o apic address */ 61*433d6423SLionel Sambuc 62*433d6423SLionel Sambuc #define LAPIC_ID (lapic_addr + 0x020) 63*433d6423SLionel Sambuc #define LAPIC_VERSION (lapic_addr + 0x030) 64*433d6423SLionel Sambuc #define LAPIC_TPR (lapic_addr + 0x080) 65*433d6423SLionel Sambuc #define LAPIC_EOI (lapic_addr + 0x0b0) 66*433d6423SLionel Sambuc #define LAPIC_LDR (lapic_addr + 0x0d0) 67*433d6423SLionel Sambuc #define LAPIC_DFR (lapic_addr + 0x0e0) 68*433d6423SLionel Sambuc #define LAPIC_SIVR (lapic_addr + 0x0f0) 69*433d6423SLionel Sambuc #define LAPIC_ISR (lapic_addr + 0x100) 70*433d6423SLionel Sambuc #define LAPIC_TMR (lapic_addr + 0x180) 71*433d6423SLionel Sambuc #define LAPIC_IRR (lapic_addr + 0x200) 72*433d6423SLionel Sambuc #define LAPIC_ESR (lapic_addr + 0x280) 73*433d6423SLionel Sambuc #define LAPIC_ICR1 (lapic_addr + 0x300) 74*433d6423SLionel Sambuc #define LAPIC_ICR2 (lapic_addr + 0x310) 75*433d6423SLionel Sambuc #define LAPIC_LVTTR (lapic_addr + 0x320) 76*433d6423SLionel Sambuc #define LAPIC_LVTTMR (lapic_addr + 0x330) 77*433d6423SLionel Sambuc #define LAPIC_LVTPCR (lapic_addr + 0x340) 78*433d6423SLionel Sambuc #define LAPIC_LINT0 (lapic_addr + 0x350) 79*433d6423SLionel Sambuc #define LAPIC_LINT1 (lapic_addr + 0x360) 80*433d6423SLionel Sambuc #define LAPIC_LVTER (lapic_addr + 0x370) 81*433d6423SLionel Sambuc #define LAPIC_TIMER_ICR (lapic_addr + 0x380) 82*433d6423SLionel Sambuc #define LAPIC_TIMER_CCR (lapic_addr + 0x390) 83*433d6423SLionel Sambuc #define LAPIC_TIMER_DCR (lapic_addr + 0x3e0) 84*433d6423SLionel Sambuc 85*433d6423SLionel Sambuc #define IOAPIC_ID 0x0 86*433d6423SLionel Sambuc #define IOAPIC_VERSION 0x1 87*433d6423SLionel Sambuc #define IOAPIC_ARB 0x2 88*433d6423SLionel Sambuc #define IOAPIC_REDIR_TABLE 0x10 89*433d6423SLionel Sambuc 90*433d6423SLionel Sambuc #define APIC_TIMER_INT_VECTOR 0xf0 91*433d6423SLionel Sambuc #define APIC_SMP_SCHED_PROC_VECTOR 0xf1 92*433d6423SLionel Sambuc #define APIC_SMP_CPU_HALT_VECTOR 0xf2 93*433d6423SLionel Sambuc #define APIC_ERROR_INT_VECTOR 0xfe 94*433d6423SLionel Sambuc #define APIC_SPURIOUS_INT_VECTOR 0xff 95*433d6423SLionel Sambuc 96*433d6423SLionel Sambuc #ifndef __ASSEMBLY__ 97*433d6423SLionel Sambuc 98*433d6423SLionel Sambuc #include "kernel/kernel.h" 99*433d6423SLionel Sambuc 100*433d6423SLionel Sambuc EXTERN vir_bytes lapic_addr; 101*433d6423SLionel Sambuc EXTERN vir_bytes lapic_eoi_addr; 102*433d6423SLionel Sambuc EXTERN int ioapic_enabled; 103*433d6423SLionel Sambuc EXTERN int bsp_lapic_id; 104*433d6423SLionel Sambuc 105*433d6423SLionel Sambuc #define MAX_NR_IOAPICS 32 106*433d6423SLionel Sambuc #define MAX_IOAPIC_IRQS 64 107*433d6423SLionel Sambuc 108*433d6423SLionel Sambuc EXTERN int ioapic_enabled; 109*433d6423SLionel Sambuc 110*433d6423SLionel Sambuc struct io_apic { 111*433d6423SLionel Sambuc unsigned id; 112*433d6423SLionel Sambuc vir_bytes addr; /* presently used address */ 113*433d6423SLionel Sambuc phys_bytes paddr; /* where is it in phys space */ 114*433d6423SLionel Sambuc vir_bytes vaddr; /* address after paging is on */ 115*433d6423SLionel Sambuc unsigned pins; 116*433d6423SLionel Sambuc unsigned gsi_base; 117*433d6423SLionel Sambuc }; 118*433d6423SLionel Sambuc 119*433d6423SLionel Sambuc EXTERN struct io_apic io_apic[MAX_NR_IOAPICS]; 120*433d6423SLionel Sambuc EXTERN unsigned nioapics; 121*433d6423SLionel Sambuc 122*433d6423SLionel Sambuc EXTERN u32_t lapic_addr_vaddr; /* we remember the virtual address here until we 123*433d6423SLionel Sambuc switch to paging */ 124*433d6423SLionel Sambuc 125*433d6423SLionel Sambuc int lapic_enable(unsigned cpu); 126*433d6423SLionel Sambuc void ioapic_unmask_irq(unsigned irq); 127*433d6423SLionel Sambuc void ioapic_mask_irq(unsigned irq); 128*433d6423SLionel Sambuc void ioapic_reset_pic(void); 129*433d6423SLionel Sambuc 130*433d6423SLionel Sambuc EXTERN int ioapic_enabled; 131*433d6423SLionel Sambuc EXTERN unsigned nioapics; 132*433d6423SLionel Sambuc 133*433d6423SLionel Sambuc void lapic_microsec_sleep(unsigned count); 134*433d6423SLionel Sambuc void ioapic_disable_irqs(u32_t irqs); 135*433d6423SLionel Sambuc void ioapic_enable_irqs(u32_t irqs); 136*433d6423SLionel Sambuc 137*433d6423SLionel Sambuc int lapic_enable(unsigned cpu); 138*433d6423SLionel Sambuc void lapic_disable(void); 139*433d6423SLionel Sambuc 140*433d6423SLionel Sambuc void ioapic_disable_all(void); 141*433d6423SLionel Sambuc int ioapic_enable_all(void); 142*433d6423SLionel Sambuc 143*433d6423SLionel Sambuc int detect_ioapics(void); 144*433d6423SLionel Sambuc void apic_idt_init(int reset); 145*433d6423SLionel Sambuc 146*433d6423SLionel Sambuc #ifdef CONFIG_SMP 147*433d6423SLionel Sambuc int apic_send_startup_ipi(unsigned cpu, phys_bytes trampoline); 148*433d6423SLionel Sambuc int apic_send_init_ipi(unsigned cpu, phys_bytes trampoline); 149*433d6423SLionel Sambuc unsigned int apicid(void); 150*433d6423SLionel Sambuc void ioapic_set_id(u32_t addr, unsigned int id); 151*433d6423SLionel Sambuc #else 152*433d6423SLionel Sambuc int apic_single_cpu_init(void); 153*433d6423SLionel Sambuc #endif 154*433d6423SLionel Sambuc 155*433d6423SLionel Sambuc void lapic_set_timer_periodic(const unsigned freq); 156*433d6423SLionel Sambuc void lapic_set_timer_one_shot(const u32_t value); 157*433d6423SLionel Sambuc void lapic_stop_timer(void); 158*433d6423SLionel Sambuc void lapic_restart_timer(void); 159*433d6423SLionel Sambuc 160*433d6423SLionel Sambuc void ioapic_set_irq(unsigned irq); 161*433d6423SLionel Sambuc void ioapic_unset_irq(unsigned irq); 162*433d6423SLionel Sambuc 163*433d6423SLionel Sambuc /* signal the end of interrupt handler to apic */ 164*433d6423SLionel Sambuc #define apic_eoi() do { *((volatile u32_t *) lapic_eoi_addr) = 0; } while(0) 165*433d6423SLionel Sambuc 166*433d6423SLionel Sambuc void ioapic_eoi(int irq); 167*433d6423SLionel Sambuc 168*433d6423SLionel Sambuc void dump_apic_irq_state(void); 169*433d6423SLionel Sambuc 170*433d6423SLionel Sambuc void apic_send_ipi(unsigned vector, unsigned cpu, int type); 171*433d6423SLionel Sambuc 172*433d6423SLionel Sambuc void apic_ipi_sched_intr(void); 173*433d6423SLionel Sambuc void apic_ipi_halt_intr(void); 174*433d6423SLionel Sambuc 175*433d6423SLionel Sambuc #define APIC_IPI_DEST 0 176*433d6423SLionel Sambuc #define APIC_IPI_SELF 1 177*433d6423SLionel Sambuc #define APIC_IPI_TO_ALL 2 178*433d6423SLionel Sambuc #define APIC_IPI_TO_ALL_BUT_SELF 3 179*433d6423SLionel Sambuc 180*433d6423SLionel Sambuc #define apic_send_ipi_single(vector,cpu) \ 181*433d6423SLionel Sambuc apic_send_ipi(vector, cpu, APIC_IPI_DEST); 182*433d6423SLionel Sambuc #define apic_send_ipi_self(vector) \ 183*433d6423SLionel Sambuc apic_send_ipi(vector, 0, APIC_IPI_SELF) 184*433d6423SLionel Sambuc #define apic_send_ipi_all(vector) \ 185*433d6423SLionel Sambuc apic_send_ipi (vector, 0, APIC_IPI_TO_ALL) 186*433d6423SLionel Sambuc #define apic_send_ipi_allbutself(vector) \ 187*433d6423SLionel Sambuc apic_send_ipi (vector, 0, APIC_IPI_TO_ALL_BUT_SELF); 188*433d6423SLionel Sambuc 189*433d6423SLionel Sambuc 190*433d6423SLionel Sambuc #include <minix/cpufeature.h> 191*433d6423SLionel Sambuc 192*433d6423SLionel Sambuc #define cpu_feature_apic_on_chip() _cpufeature(_CPUF_I386_APIC_ON_CHIP) 193*433d6423SLionel Sambuc 194*433d6423SLionel Sambuc #define lapic_read(what) (*((volatile u32_t *)((what)))) 195*433d6423SLionel Sambuc #define lapic_write(what, data) do { \ 196*433d6423SLionel Sambuc (*((volatile u32_t *)((what)))) = data; \ 197*433d6423SLionel Sambuc } while(0) 198*433d6423SLionel Sambuc 199*433d6423SLionel Sambuc #endif /* __ASSEMBLY__ */ 200*433d6423SLionel Sambuc 201*433d6423SLionel Sambuc #endif /* __APIC_H__ */ 202