1c865f654SCornelia Huck #ifndef _X86_APIC_H_
2c865f654SCornelia Huck #define _X86_APIC_H_
37d36db35SAvi Kivity
4f399af21SSean Christopherson #include <bitops.h>
57d36db35SAvi Kivity #include <stdint.h>
6*d467e659SSean Christopherson
77d36db35SAvi Kivity #include "apic-defs.h"
8*d467e659SSean Christopherson #include "smp.h"
97d36db35SAvi Kivity
1018a34cceSNadav Amit extern u8 id_map[MAX_TEST_CPUS];
1118a34cceSNadav Amit
127d36db35SAvi Kivity typedef struct {
137d36db35SAvi Kivity uint8_t vector;
147d36db35SAvi Kivity uint8_t delivery_mode:3;
157d36db35SAvi Kivity uint8_t dest_mode:1;
167d36db35SAvi Kivity uint8_t delivery_status:1;
177d36db35SAvi Kivity uint8_t polarity:1;
187d36db35SAvi Kivity uint8_t remote_irr:1;
197d36db35SAvi Kivity uint8_t trig_mode:1;
207d36db35SAvi Kivity uint8_t mask:1;
217d36db35SAvi Kivity uint8_t reserve:7;
227d36db35SAvi Kivity uint8_t reserved[4];
237d36db35SAvi Kivity uint8_t dest_id;
247d36db35SAvi Kivity } ioapic_redir_entry_t;
257d36db35SAvi Kivity
260172b95cSPeter Xu typedef enum trigger_mode {
270172b95cSPeter Xu TRIGGER_EDGE = 0,
280172b95cSPeter Xu TRIGGER_LEVEL,
290172b95cSPeter Xu TRIGGER_MAX,
300172b95cSPeter Xu } trigger_mode_t;
310172b95cSPeter Xu
327d36db35SAvi Kivity void mask_pic_interrupts(void);
337d36db35SAvi Kivity
340f187a08SSteve Rutherford void eoi(void);
35e0a5cfcaSPaolo Bonzini uint8_t apic_get_tpr(void);
36e0a5cfcaSPaolo Bonzini void apic_set_tpr(uint8_t tpr);
370f187a08SSteve Rutherford
387d36db35SAvi Kivity void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e);
397d36db35SAvi Kivity void ioapic_write_reg(unsigned reg, uint32_t value);
400f187a08SSteve Rutherford ioapic_redir_entry_t ioapic_read_redir(unsigned line);
410f187a08SSteve Rutherford uint32_t ioapic_read_reg(unsigned reg);
420f187a08SSteve Rutherford
4322207960SLiran Alon void ioapic_set_redir(unsigned line, unsigned vec,
44f66d11caSArbel Moshe trigger_mode_t trig_mode);
45f66d11caSArbel Moshe
460f187a08SSteve Rutherford void set_mask(unsigned line, int mask);
477d36db35SAvi Kivity
48f66d11caSArbel Moshe void set_irq_line(unsigned line, int val);
49f66d11caSArbel Moshe
507d36db35SAvi Kivity void enable_apic(void);
517d36db35SAvi Kivity uint32_t apic_read(unsigned reg);
527c5f3ee9SPaolo Bonzini bool apic_read_bit(unsigned reg, int n);
537d36db35SAvi Kivity void apic_write(unsigned reg, uint32_t val);
547d36db35SAvi Kivity void apic_icr_write(uint32_t val, uint32_t dest);
557d36db35SAvi Kivity uint32_t apic_id(void);
56d8de5a33SSean Christopherson uint32_t pre_boot_apic_id(void);
57d8de5a33SSean Christopherson
587d36db35SAvi Kivity
597d36db35SAvi Kivity int enable_x2apic(void);
60e38858bcSJim Mattson void disable_apic(void);
61a222b5e2SRadim Krčmář void reset_apic(void);
6218a34cceSNadav Amit void init_apic_map(void);
637d36db35SAvi Kivity
6411a7a966SMaxim Levitsky void apic_cleanup_timer(void);
6511a7a966SMaxim Levitsky void apic_setup_timer(int vector, u32 mode);
6611a7a966SMaxim Levitsky
6711a7a966SMaxim Levitsky void apic_start_timer(u32 counter);
6811a7a966SMaxim Levitsky void apic_stop_timer(void);
6911a7a966SMaxim Levitsky
70268752cdSMarc Orr /* Converts byte-addressable APIC register offset to 4-byte offset. */
apic_reg_index(u32 reg)71268752cdSMarc Orr static inline u32 apic_reg_index(u32 reg)
72268752cdSMarc Orr {
73268752cdSMarc Orr return reg >> 2;
74268752cdSMarc Orr }
75268752cdSMarc Orr
x2apic_msr(u32 reg)762a2546b7SMarc Orr static inline u32 x2apic_msr(u32 reg)
772a2546b7SMarc Orr {
782a2546b7SMarc Orr return APIC_BASE_MSR + (reg >> 4);
792a2546b7SMarc Orr }
802a2546b7SMarc Orr
apic_lvt_entry_supported(int idx)8119697109SNadav Amit static inline bool apic_lvt_entry_supported(int idx)
8219697109SNadav Amit {
8319697109SNadav Amit return GET_APIC_MAXLVT(apic_read(APIC_LVR)) >= idx;
8419697109SNadav Amit }
8519697109SNadav Amit
task_priority_class(u8 vector)86a917f7c7SMarc Orr static inline u8 task_priority_class(u8 vector)
87a917f7c7SMarc Orr {
88a917f7c7SMarc Orr return vector >> 4;
89a917f7c7SMarc Orr }
90a917f7c7SMarc Orr
91f399af21SSean Christopherson enum x2apic_reg_semantics {
92f399af21SSean Christopherson X2APIC_INVALID = 0,
93f399af21SSean Christopherson X2APIC_READABLE = BIT(0),
94f399af21SSean Christopherson X2APIC_WRITABLE = BIT(1),
95f399af21SSean Christopherson X2APIC_RO = X2APIC_READABLE,
96f399af21SSean Christopherson X2APIC_WO = X2APIC_WRITABLE,
97f399af21SSean Christopherson X2APIC_RW = X2APIC_READABLE | X2APIC_WRITABLE,
98f399af21SSean Christopherson };
99f399af21SSean Christopherson
get_x2apic_reg_semantics(u32 reg)100f399af21SSean Christopherson static inline enum x2apic_reg_semantics get_x2apic_reg_semantics(u32 reg)
1012a2546b7SMarc Orr {
102f399af21SSean Christopherson assert(!(reg & 0xf));
103f399af21SSean Christopherson
1042a2546b7SMarc Orr switch (reg) {
105f399af21SSean Christopherson case APIC_ID:
106f399af21SSean Christopherson case APIC_LVR:
107f399af21SSean Christopherson case APIC_PROCPRI:
108f399af21SSean Christopherson case APIC_LDR:
109f399af21SSean Christopherson case APIC_ISR ... APIC_ISR + 0x70:
110f399af21SSean Christopherson case APIC_TMR ... APIC_TMR + 0x70:
111f399af21SSean Christopherson case APIC_IRR ... APIC_IRR + 0x70:
112f399af21SSean Christopherson case APIC_TMCCT:
113f399af21SSean Christopherson return X2APIC_RO;
114f399af21SSean Christopherson case APIC_TASKPRI:
115f399af21SSean Christopherson case APIC_SPIV:
116f399af21SSean Christopherson case APIC_ESR:
117f399af21SSean Christopherson case APIC_ICR:
118f399af21SSean Christopherson case APIC_LVTT:
119f399af21SSean Christopherson case APIC_LVTTHMR:
120f399af21SSean Christopherson case APIC_LVTPC:
121f399af21SSean Christopherson case APIC_LVT0:
122f399af21SSean Christopherson case APIC_LVT1:
123f399af21SSean Christopherson case APIC_LVTERR:
124f399af21SSean Christopherson case APIC_TMICT:
125f399af21SSean Christopherson case APIC_TDCR:
126f399af21SSean Christopherson return X2APIC_RW;
127f399af21SSean Christopherson case APIC_EOI:
128f399af21SSean Christopherson case APIC_SELF_IPI:
129f399af21SSean Christopherson return X2APIC_WO;
13019697109SNadav Amit case APIC_CMCI:
131f399af21SSean Christopherson if (apic_lvt_entry_supported(6))
132f399af21SSean Christopherson return X2APIC_RW;
133f399af21SSean Christopherson break;
134f399af21SSean Christopherson case APIC_RRR:
135f399af21SSean Christopherson case APIC_DFR:
136f399af21SSean Christopherson case APIC_ICR2:
1372a2546b7SMarc Orr default:
138f399af21SSean Christopherson break;
1392a2546b7SMarc Orr }
140f399af21SSean Christopherson return X2APIC_INVALID;
1412a2546b7SMarc Orr }
1422a2546b7SMarc Orr
1437d36db35SAvi Kivity #endif
144