1c865f654SCornelia Huck #ifndef _X86_APIC_H_ 2c865f654SCornelia Huck #define _X86_APIC_H_ 37d36db35SAvi Kivity 4*f399af21SSean Christopherson #include <bitops.h> 57d36db35SAvi Kivity #include <stdint.h> 67d36db35SAvi Kivity #include "apic-defs.h" 77d36db35SAvi Kivity 818a34cceSNadav Amit extern u8 id_map[MAX_TEST_CPUS]; 918a34cceSNadav Amit 107d36db35SAvi Kivity typedef struct { 117d36db35SAvi Kivity uint8_t vector; 127d36db35SAvi Kivity uint8_t delivery_mode:3; 137d36db35SAvi Kivity uint8_t dest_mode:1; 147d36db35SAvi Kivity uint8_t delivery_status:1; 157d36db35SAvi Kivity uint8_t polarity:1; 167d36db35SAvi Kivity uint8_t remote_irr:1; 177d36db35SAvi Kivity uint8_t trig_mode:1; 187d36db35SAvi Kivity uint8_t mask:1; 197d36db35SAvi Kivity uint8_t reserve:7; 207d36db35SAvi Kivity uint8_t reserved[4]; 217d36db35SAvi Kivity uint8_t dest_id; 227d36db35SAvi Kivity } ioapic_redir_entry_t; 237d36db35SAvi Kivity 240172b95cSPeter Xu typedef enum trigger_mode { 250172b95cSPeter Xu TRIGGER_EDGE = 0, 260172b95cSPeter Xu TRIGGER_LEVEL, 270172b95cSPeter Xu TRIGGER_MAX, 280172b95cSPeter Xu } trigger_mode_t; 290172b95cSPeter Xu 307d36db35SAvi Kivity void mask_pic_interrupts(void); 317d36db35SAvi Kivity 320f187a08SSteve Rutherford void eoi(void); 33e0a5cfcaSPaolo Bonzini uint8_t apic_get_tpr(void); 34e0a5cfcaSPaolo Bonzini void apic_set_tpr(uint8_t tpr); 350f187a08SSteve Rutherford 367d36db35SAvi Kivity void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e); 377d36db35SAvi Kivity void ioapic_write_reg(unsigned reg, uint32_t value); 380f187a08SSteve Rutherford ioapic_redir_entry_t ioapic_read_redir(unsigned line); 390f187a08SSteve Rutherford uint32_t ioapic_read_reg(unsigned reg); 400f187a08SSteve Rutherford 4122207960SLiran Alon void ioapic_set_redir(unsigned line, unsigned vec, 42f66d11caSArbel Moshe trigger_mode_t trig_mode); 43f66d11caSArbel Moshe 440f187a08SSteve Rutherford void set_mask(unsigned line, int mask); 457d36db35SAvi Kivity 46f66d11caSArbel Moshe void set_irq_line(unsigned line, int val); 47f66d11caSArbel Moshe 487d36db35SAvi Kivity void enable_apic(void); 497d36db35SAvi Kivity uint32_t apic_read(unsigned reg); 507c5f3ee9SPaolo Bonzini bool apic_read_bit(unsigned reg, int n); 517d36db35SAvi Kivity void apic_write(unsigned reg, uint32_t val); 527d36db35SAvi Kivity void apic_icr_write(uint32_t val, uint32_t dest); 537d36db35SAvi Kivity uint32_t apic_id(void); 54d8de5a33SSean Christopherson uint32_t pre_boot_apic_id(void); 55d8de5a33SSean Christopherson 567d36db35SAvi Kivity 577d36db35SAvi Kivity int enable_x2apic(void); 58e38858bcSJim Mattson void disable_apic(void); 59a222b5e2SRadim Krčmář void reset_apic(void); 6018a34cceSNadav Amit void init_apic_map(void); 617d36db35SAvi Kivity 62268752cdSMarc Orr /* Converts byte-addressable APIC register offset to 4-byte offset. */ 63268752cdSMarc Orr static inline u32 apic_reg_index(u32 reg) 64268752cdSMarc Orr { 65268752cdSMarc Orr return reg >> 2; 66268752cdSMarc Orr } 67268752cdSMarc Orr 682a2546b7SMarc Orr static inline u32 x2apic_msr(u32 reg) 692a2546b7SMarc Orr { 702a2546b7SMarc Orr return APIC_BASE_MSR + (reg >> 4); 712a2546b7SMarc Orr } 722a2546b7SMarc Orr 7319697109SNadav Amit static inline bool apic_lvt_entry_supported(int idx) 7419697109SNadav Amit { 7519697109SNadav Amit return GET_APIC_MAXLVT(apic_read(APIC_LVR)) >= idx; 7619697109SNadav Amit } 7719697109SNadav Amit 78*f399af21SSean Christopherson enum x2apic_reg_semantics { 79*f399af21SSean Christopherson X2APIC_INVALID = 0, 80*f399af21SSean Christopherson X2APIC_READABLE = BIT(0), 81*f399af21SSean Christopherson X2APIC_WRITABLE = BIT(1), 82*f399af21SSean Christopherson X2APIC_RO = X2APIC_READABLE, 83*f399af21SSean Christopherson X2APIC_WO = X2APIC_WRITABLE, 84*f399af21SSean Christopherson X2APIC_RW = X2APIC_READABLE | X2APIC_WRITABLE, 85*f399af21SSean Christopherson }; 86*f399af21SSean Christopherson 87*f399af21SSean Christopherson static inline enum x2apic_reg_semantics get_x2apic_reg_semantics(u32 reg) 882a2546b7SMarc Orr { 89*f399af21SSean Christopherson assert(!(reg & 0xf)); 90*f399af21SSean Christopherson 912a2546b7SMarc Orr switch (reg) { 92*f399af21SSean Christopherson case APIC_ID: 93*f399af21SSean Christopherson case APIC_LVR: 94*f399af21SSean Christopherson case APIC_PROCPRI: 95*f399af21SSean Christopherson case APIC_LDR: 96*f399af21SSean Christopherson case APIC_ISR ... APIC_ISR + 0x70: 97*f399af21SSean Christopherson case APIC_TMR ... APIC_TMR + 0x70: 98*f399af21SSean Christopherson case APIC_IRR ... APIC_IRR + 0x70: 99*f399af21SSean Christopherson case APIC_TMCCT: 100*f399af21SSean Christopherson return X2APIC_RO; 101*f399af21SSean Christopherson case APIC_TASKPRI: 102*f399af21SSean Christopherson case APIC_SPIV: 103*f399af21SSean Christopherson case APIC_ESR: 104*f399af21SSean Christopherson case APIC_ICR: 105*f399af21SSean Christopherson case APIC_LVTT: 106*f399af21SSean Christopherson case APIC_LVTTHMR: 107*f399af21SSean Christopherson case APIC_LVTPC: 108*f399af21SSean Christopherson case APIC_LVT0: 109*f399af21SSean Christopherson case APIC_LVT1: 110*f399af21SSean Christopherson case APIC_LVTERR: 111*f399af21SSean Christopherson case APIC_TMICT: 112*f399af21SSean Christopherson case APIC_TDCR: 113*f399af21SSean Christopherson return X2APIC_RW; 114*f399af21SSean Christopherson case APIC_EOI: 115*f399af21SSean Christopherson case APIC_SELF_IPI: 116*f399af21SSean Christopherson return X2APIC_WO; 11719697109SNadav Amit case APIC_CMCI: 118*f399af21SSean Christopherson if (apic_lvt_entry_supported(6)) 119*f399af21SSean Christopherson return X2APIC_RW; 120*f399af21SSean Christopherson break; 121*f399af21SSean Christopherson case APIC_RRR: 122*f399af21SSean Christopherson case APIC_DFR: 123*f399af21SSean Christopherson case APIC_ICR2: 1242a2546b7SMarc Orr default: 125*f399af21SSean Christopherson break; 1262a2546b7SMarc Orr } 127*f399af21SSean Christopherson return X2APIC_INVALID; 1282a2546b7SMarc Orr } 1292a2546b7SMarc Orr 1307d36db35SAvi Kivity #endif 131