1 #ifndef _X86_APIC_H_ 2 #define _X86_APIC_H_ 3 4 #include <bitops.h> 5 #include <stdint.h> 6 #include "apic-defs.h" 7 8 extern u8 id_map[MAX_TEST_CPUS]; 9 10 typedef struct { 11 uint8_t vector; 12 uint8_t delivery_mode:3; 13 uint8_t dest_mode:1; 14 uint8_t delivery_status:1; 15 uint8_t polarity:1; 16 uint8_t remote_irr:1; 17 uint8_t trig_mode:1; 18 uint8_t mask:1; 19 uint8_t reserve:7; 20 uint8_t reserved[4]; 21 uint8_t dest_id; 22 } ioapic_redir_entry_t; 23 24 typedef enum trigger_mode { 25 TRIGGER_EDGE = 0, 26 TRIGGER_LEVEL, 27 TRIGGER_MAX, 28 } trigger_mode_t; 29 30 void mask_pic_interrupts(void); 31 32 void eoi(void); 33 uint8_t apic_get_tpr(void); 34 void apic_set_tpr(uint8_t tpr); 35 36 void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e); 37 void ioapic_write_reg(unsigned reg, uint32_t value); 38 ioapic_redir_entry_t ioapic_read_redir(unsigned line); 39 uint32_t ioapic_read_reg(unsigned reg); 40 41 void ioapic_set_redir(unsigned line, unsigned vec, 42 trigger_mode_t trig_mode); 43 44 void set_mask(unsigned line, int mask); 45 46 void set_irq_line(unsigned line, int val); 47 48 void enable_apic(void); 49 uint32_t apic_read(unsigned reg); 50 bool apic_read_bit(unsigned reg, int n); 51 void apic_write(unsigned reg, uint32_t val); 52 void apic_icr_write(uint32_t val, uint32_t dest); 53 uint32_t apic_id(void); 54 uint32_t pre_boot_apic_id(void); 55 56 57 int enable_x2apic(void); 58 void disable_apic(void); 59 void reset_apic(void); 60 void init_apic_map(void); 61 62 void apic_cleanup_timer(void); 63 void apic_setup_timer(int vector, u32 mode); 64 65 void apic_start_timer(u32 counter); 66 void apic_stop_timer(void); 67 68 /* Converts byte-addressable APIC register offset to 4-byte offset. */ 69 static inline u32 apic_reg_index(u32 reg) 70 { 71 return reg >> 2; 72 } 73 74 static inline u32 x2apic_msr(u32 reg) 75 { 76 return APIC_BASE_MSR + (reg >> 4); 77 } 78 79 static inline bool apic_lvt_entry_supported(int idx) 80 { 81 return GET_APIC_MAXLVT(apic_read(APIC_LVR)) >= idx; 82 } 83 84 static inline u8 task_priority_class(u8 vector) 85 { 86 return vector >> 4; 87 } 88 89 enum x2apic_reg_semantics { 90 X2APIC_INVALID = 0, 91 X2APIC_READABLE = BIT(0), 92 X2APIC_WRITABLE = BIT(1), 93 X2APIC_RO = X2APIC_READABLE, 94 X2APIC_WO = X2APIC_WRITABLE, 95 X2APIC_RW = X2APIC_READABLE | X2APIC_WRITABLE, 96 }; 97 98 static inline enum x2apic_reg_semantics get_x2apic_reg_semantics(u32 reg) 99 { 100 assert(!(reg & 0xf)); 101 102 switch (reg) { 103 case APIC_ID: 104 case APIC_LVR: 105 case APIC_PROCPRI: 106 case APIC_LDR: 107 case APIC_ISR ... APIC_ISR + 0x70: 108 case APIC_TMR ... APIC_TMR + 0x70: 109 case APIC_IRR ... APIC_IRR + 0x70: 110 case APIC_TMCCT: 111 return X2APIC_RO; 112 case APIC_TASKPRI: 113 case APIC_SPIV: 114 case APIC_ESR: 115 case APIC_ICR: 116 case APIC_LVTT: 117 case APIC_LVTTHMR: 118 case APIC_LVTPC: 119 case APIC_LVT0: 120 case APIC_LVT1: 121 case APIC_LVTERR: 122 case APIC_TMICT: 123 case APIC_TDCR: 124 return X2APIC_RW; 125 case APIC_EOI: 126 case APIC_SELF_IPI: 127 return X2APIC_WO; 128 case APIC_CMCI: 129 if (apic_lvt_entry_supported(6)) 130 return X2APIC_RW; 131 break; 132 case APIC_RRR: 133 case APIC_DFR: 134 case APIC_ICR2: 135 default: 136 break; 137 } 138 return X2APIC_INVALID; 139 } 140 141 #endif 142