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. */
apic_reg_index(u32 reg)71 static inline u32 apic_reg_index(u32 reg)
72 {
73 return reg >> 2;
74 }
75
x2apic_msr(u32 reg)76 static inline u32 x2apic_msr(u32 reg)
77 {
78 return APIC_BASE_MSR + (reg >> 4);
79 }
80
apic_lvt_entry_supported(int idx)81 static inline bool apic_lvt_entry_supported(int idx)
82 {
83 return GET_APIC_MAXLVT(apic_read(APIC_LVR)) >= idx;
84 }
85
task_priority_class(u8 vector)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
get_x2apic_reg_semantics(u32 reg)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