xref: /kvm-unit-tests/lib/x86/apic.h (revision c604fa931a1cb70c3649ac1b7223178fc79eab6a)
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 typedef struct {
10     uint8_t vector;
11     uint8_t delivery_mode:3;
12     uint8_t dest_mode:1;
13     uint8_t delivery_status:1;
14     uint8_t polarity:1;
15     uint8_t remote_irr:1;
16     uint8_t trig_mode:1;
17     uint8_t mask:1;
18     uint8_t reserve:7;
19     uint8_t reserved[4];
20     uint8_t dest_id;
21 } ioapic_redir_entry_t;
22 
23 typedef enum trigger_mode {
24 	TRIGGER_EDGE = 0,
25 	TRIGGER_LEVEL,
26 	TRIGGER_MAX,
27 } trigger_mode_t;
28 
29 void mask_pic_interrupts(void);
30 
31 void eoi(void);
32 uint8_t apic_get_tpr(void);
33 void apic_set_tpr(uint8_t tpr);
34 
35 void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e);
36 void ioapic_write_reg(unsigned reg, uint32_t value);
37 ioapic_redir_entry_t ioapic_read_redir(unsigned line);
38 uint32_t ioapic_read_reg(unsigned reg);
39 
40 void ioapic_set_redir(unsigned line, unsigned vec,
41 		trigger_mode_t trig_mode);
42 
43 void set_mask(unsigned line, int mask);
44 
45 void set_irq_line(unsigned line, int val);
46 
47 void enable_apic(void);
48 uint32_t apic_read(unsigned reg);
49 bool apic_read_bit(unsigned reg, int n);
50 void apic_write(unsigned reg, uint32_t val);
51 void apic_icr_write(uint32_t val, uint32_t dest);
52 uint32_t apic_id(void);
53 uint32_t pre_boot_apic_id(void);
54 
55 
56 int enable_x2apic(void);
57 void disable_apic(void);
58 void reset_apic(void);
59 void init_apic_map(void);
60 
61 /* Converts byte-addressable APIC register offset to 4-byte offset. */
62 static inline u32 apic_reg_index(u32 reg)
63 {
64 	return reg >> 2;
65 }
66 
67 static inline u32 x2apic_msr(u32 reg)
68 {
69 	return APIC_BASE_MSR + (reg >> 4);
70 }
71 
72 static inline bool apic_lvt_entry_supported(int idx)
73 {
74 	return GET_APIC_MAXLVT(apic_read(APIC_LVR)) >= idx;
75 }
76 
77 static inline bool x2apic_reg_reserved(u32 reg)
78 {
79 	switch (reg) {
80 	case 0x000 ... 0x010:
81 	case 0x040 ... 0x070:
82 	case 0x090:
83 	case 0x0c0:
84 	case 0x0e0:
85 	case 0x290 ... 0x2e0:
86 	case 0x310:
87 	case 0x3a0 ... 0x3d0:
88 	case 0x3f0:
89 		return true;
90 	case APIC_CMCI:
91 		return !apic_lvt_entry_supported(6);
92 	default:
93 		return false;
94 	}
95 }
96 
97 #endif
98