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