xref: /kvm-unit-tests/lib/x86/apic.h (revision c865f654ffe4c5955038aaf74f702ba62f3eb014)
1 #ifndef _X86_APIC_H_
2 #define _X86_APIC_H_
3 
4 #include <stdint.h>
5 #include "apic-defs.h"
6 
7 extern u8 id_map[MAX_TEST_CPUS];
8 
9 extern void *g_apic;
10 extern void *g_ioapic;
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 
57 int enable_x2apic(void);
58 void disable_apic(void);
59 void reset_apic(void);
60 void init_apic_map(void);
61 
62 /* Converts byte-addressable APIC register offset to 4-byte offset. */
63 static inline u32 apic_reg_index(u32 reg)
64 {
65 	return reg >> 2;
66 }
67 
68 static inline u32 x2apic_msr(u32 reg)
69 {
70 	return APIC_BASE_MSR + (reg >> 4);
71 }
72 
73 static inline bool apic_lvt_entry_supported(int idx)
74 {
75 	return GET_APIC_MAXLVT(apic_read(APIC_LVR)) >= idx;
76 }
77 
78 static inline bool x2apic_reg_reserved(u32 reg)
79 {
80 	switch (reg) {
81 	case 0x000 ... 0x010:
82 	case 0x040 ... 0x070:
83 	case 0x090:
84 	case 0x0c0:
85 	case 0x0e0:
86 	case 0x290 ... 0x2e0:
87 	case 0x310:
88 	case 0x3a0 ... 0x3d0:
89 	case 0x3f0:
90 		return true;
91 	case APIC_CMCI:
92 		return !apic_lvt_entry_supported(6);
93 	default:
94 		return false;
95 	}
96 }
97 
98 #endif
99