hal:
[reactos.git] / reactos / hal / halx86 / include / apic.h
1 /*
2 *
3 */
4
5 #ifndef __INTERNAL_HAL_APIC_H
6 #define __INTERNAL_HAL_APIC_H
7
8 #define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */
9
10 /* APIC Register Address Map */
11 #define APIC_ID 0x0020 /* Local APIC ID Register (R/W) */
12 #define APIC_VER 0x0030 /* Local APIC Version Register (R) */
13 #define APIC_TPR 0x0080 /* Task Priority Register (R/W) */
14 #define APIC_APR 0x0090 /* Arbitration Priority Register (R) */
15 #define APIC_PPR 0x00A0 /* Processor Priority Register (R) */
16 #define APIC_EOI 0x00B0 /* EOI Register (W) */
17 #define APIC_LDR 0x00D0 /* Logical Destination Register (R/W) */
18 #define APIC_DFR 0x00E0 /* Destination Format Register (0-27 R, 28-31 R/W) */
19 #define APIC_SIVR 0x00F0 /* Spurious Interrupt Vector Register (0-3 R, 4-9 R/W) */
20 #define APIC_ISR 0x0100 /* Interrupt Service Register 0-255 (R) */
21 #define APIC_TMR 0x0180 /* Trigger Mode Register 0-255 (R) */
22 #define APIC_IRR 0x0200 /* Interrupt Request Register 0-255 (r) */
23 #define APIC_ESR 0x0280 /* Error Status Register (R) */
24 #define APIC_ICR0 0x0300 /* Interrupt Command Register 0-31 (R/W) */
25 #define APIC_ICR1 0x0310 /* Interrupt Command Register 32-63 (R/W) */
26 #define APIC_LVTT 0x0320 /* Local Vector Table (Timer) (R/W) */
27 #define APIC_LVTTHMR 0x0330
28 #define APIC_LVTPC 0x0340 /* Performance Counter LVT (R/W) */
29 #define APIC_LINT0 0x0350 /* Local Vector Table (LINT0) (R/W) */
30 #define APIC_LINT1 0x0360 /* Local Vector Table (LINT1) (R/W) */
31 #define APIC_LVT3 0x0370 /* Local Vector Table (Error) (R/W) */
32 #define APIC_ICRT 0x0380 /* Initial Count Register for Timer (R/W) */
33 #define APIC_CCRT 0x0390 /* Current Count Register for Timer (R) */
34 #define APIC_TDCR 0x03E0 /* Timer Divide Configuration Register (R/W) */
35
36 #define APIC_ID_MASK (0xF << 24)
37 #define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24)
38 #define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF)
39 #define APIC_VER_MASK 0xFF00FF
40 #define GET_APIC_VERSION(x) ((x) & 0xFF)
41 #define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF)
42
43 #define APIC_TPR_PRI 0xFF
44 #define APIC_TPR_INT 0xF0
45 #define APIC_TPR_SUB 0xF
46 #define APIC_TPR_MAX 0xFF /* Maximum priority */
47 #define APIC_TPR_MIN 0x20 /* Minimum priority */
48
49 #define APIC_LDR_MASK (0xFF << 24)
50
51 #define APIC_SIVR_ENABLE (0x1 << 8)
52 #define APIC_SIVR_FOCUS (0x1 << 9)
53
54 #define APIC_ESR_MASK (0xFE << 0) /* Error Mask */
55
56 #define APIC_ICR0_VECTOR (0xFF << 0) /* Vector */
57 #define APIC_ICR0_DM (0x7 << 8) /* Delivery Mode */
58 #define APIC_ICR0_DESTM (0x1 << 11) /* Destination Mode */
59 #define APIC_ICR0_DS (0x1 << 12) /* Delivery Status */
60 #define APIC_ICR0_LEVEL (0x1 << 14) /* Level */
61 #define APIC_ICR0_TM (0x1 << 15) /* Trigger Mode */
62 #define APIC_ICR0_DESTS (0x3 << 18) /* Destination Shorthand */
63
64 /* Delivery Modes */
65 #define APIC_DM_FIXED (0x0 << 8)
66 #define APIC_DM_LOWEST (0x1 << 8)
67 #define APIC_DM_SMI (0x2 << 8)
68 #define APIC_DM_REMRD (0x3 << 8)
69 #define APIC_DM_NMI (0x4 << 8)
70 #define APIC_DM_INIT (0x5 << 8)
71 #define APIC_DM_STARTUP (0x6 << 8)
72 #define APIC_DM_EXTINT (0x7 << 8)
73 #define GET_APIC_DELIVERY_MODE(x) (((x) >> 8) & 0x7)
74 #define SET_APIC_DELIVERY_MODE(x,y) (((x) & ~0x700) | ((y) << 8))
75
76 /* Destination Shorthand values */
77 #define APIC_ICR0_DESTS_FIELD (0x0 << 0)
78 #define APIC_ICR0_DESTS_SELF (0x1 << 18)
79 #define APIC_ICR0_DESTS_ALL (0x2 << 18)
80 #define APIC_ICR0_DESTS_ALL_BUT_SELF (0x3 << 18)
81
82 #define APIC_ICR0_LEVEL_DEASSERT (0x0 << 14) /* Deassert level */
83 #define APIC_ICR0_LEVEL_ASSERT (0x1 << 14) /* Assert level */
84
85 #define GET_APIC_DEST_FIELD(x) (((x) >> 24) & 0xFF)
86 #define SET_APIC_DEST_FIELD(x) (((x) & 0xFF) << 24)
87
88 #define GET_APIC_TIMER_BASE(x) (((x) >> 18) & 0x3)
89 #define SET_APIC_TIMER_BASE(x) ((x) << 18)
90 #define APIC_TIMER_BASE_CLKIN 0x0
91 #define APIC_TIMER_BASE_TMBASE 0x1
92 #define APIC_TIMER_BASE_DIV 0x2
93
94 #define APIC_LVT_VECTOR (0xFF << 0) /* Vector */
95 #define APIC_LVT_DS (0x1 << 12) /* Delivery Status */
96 #define APIC_LVT_REMOTE_IRR (0x1 << 14) /* Remote IRR */
97 #define APIC_LVT_LEVEL_TRIGGER (0x1 << 15) /* Lvel Triggered */
98 #define APIC_LVT_MASKED (0x1 << 16) /* Mask */
99 #define APIC_LVT_PERIODIC (0x1 << 17) /* Timer Mode */
100
101 #define APIC_LVT3_DM (0x7 << 8)
102 #define APIC_LVT3_IIPP (0x1 << 13)
103 #define APIC_LVT3_TM (0x1 << 15)
104 #define APIC_LVT3_MASKED (0x1 << 16)
105 #define APIC_LVT3_OS (0x1 << 17)
106
107 #define APIC_TDCR_TMBASE (0x1 << 2)
108 #define APIC_TDCR_MASK 0x0F
109 #define APIC_TDCR_2 0x00
110 #define APIC_TDCR_4 0x01
111 #define APIC_TDCR_8 0x02
112 #define APIC_TDCR_16 0x03
113 #define APIC_TDCR_32 0x08
114 #define APIC_TDCR_64 0x09
115 #define APIC_TDCR_128 0x0A
116 #define APIC_TDCR_1 0x0B
117
118 #define APIC_LVT_VECTOR (0xFF << 0) /* Vector */
119 #define APIC_LVT_DS (0x1 << 12) /* Delivery Status */
120 #define APIC_LVT_REMOTE_IRR (0x1 << 14) /* Remote IRR */
121 #define APIC_LVT_LEVEL_TRIGGER (0x1 << 15) /* Lvel Triggered */
122 #define APIC_LVT_MASKED (0x1 << 16) /* Mask */
123 #define APIC_LVT_PERIODIC (0x1 << 17) /* Timer Mode */
124
125 #define APIC_LVT3_DM (0x7 << 8)
126 #define APIC_LVT3_IIPP (0x1 << 13)
127 #define APIC_LVT3_TM (0x1 << 15)
128 #define APIC_LVT3_MASKED (0x1 << 16)
129 #define APIC_LVT3_OS (0x1 << 17)
130
131 #define APIC_TDCR_TMBASE (0x1 << 2)
132 #define APIC_TDCR_MASK 0x0F
133 #define APIC_TDCR_2 0x00
134 #define APIC_TDCR_4 0x01
135 #define APIC_TDCR_8 0x02
136 #define APIC_TDCR_16 0x03
137 #define APIC_TDCR_32 0x08
138 #define APIC_TDCR_64 0x09
139 #define APIC_TDCR_128 0x0A
140 #define APIC_TDCR_1 0x0B
141
142 #define APIC_TARGET_SELF 0x100
143 #define APIC_TARGET_ALL 0x200
144 #define APIC_TARGET_ALL_BUT_SELF 0x300
145
146 #define APIC_INTEGRATED(version) (version & 0xF0)
147
148 typedef enum {
149 amPIC = 0, /* IMCR and PIC compatibility mode */
150 amVWIRE /* Virtual Wire compatibility mode */
151 } APIC_MODE;
152
153 #ifdef CONFIG_SMP
154 #define MAX_CPU 32
155 #else
156 #define MAX_CPU 1
157 #endif
158
159 /*
160 * Local APIC timer IRQ vector is on a different priority level,
161 * to work around the 'lost local interrupt if more than 2 IRQ
162 * sources per level' errata.
163 */
164 #define LOCAL_TIMER_VECTOR 0xEF
165
166 #define IPI_VECTOR 0xFB
167 #define ERROR_VECTOR 0xFE
168 #define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
169
170 /* CPU flags */
171 #define CPU_USABLE 0x01 /* 1 if the CPU is usable (ie. can be used) */
172 #define CPU_ENABLED 0x02 /* 1 if the CPU is enabled */
173 #define CPU_BSP 0x04 /* 1 if the CPU is the bootstrap processor */
174 #define CPU_TSC 0x08 /* 1 if the CPU has a time stamp counter */
175
176 typedef struct _CPU_INFO
177 {
178 UCHAR Flags; /* CPU flags */
179 UCHAR APICId; /* Local APIC ID */
180 UCHAR APICVersion; /* Local APIC version */
181 // UCHAR MaxLVT; /* Number of LVT registers */
182 ULONG BusSpeed; /* BUS speed */
183 ULONG CoreSpeed; /* Core speed */
184 UCHAR Padding[16-12]; /* Padding to 16-byte */
185 } CPU_INFO, *PCPU_INFO;
186
187 extern ULONG CPUCount; /* Total number of CPUs */
188 extern ULONG BootCPU; /* Bootstrap processor */
189 extern ULONG OnlineCPUs; /* Bitmask of online CPUs */
190 extern CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */
191
192 /* Prototypes */
193
194 __inline VOID APICWrite(ULONG Offset, ULONG Value);
195 __inline ULONG APICRead(ULONG Offset);
196 VOID APICSendIPI(ULONG Target, ULONG Mode);
197 VOID APICSetup(VOID);
198 VOID HaliInitBSP(VOID);
199 VOID APICSyncArbIDs(VOID);
200 __inline VOID APICSendEOI(VOID);
201 VOID APICCalibrateTimer(ULONG CPU);
202 VOID HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack);
203
204 static __inline ULONG ThisCPU(VOID)
205 {
206 return (APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
207 }
208
209
210 #endif
211
212
213 /* EOF */
214