Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 436 lines (379 sloc) 11.957 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
/*
* GPL HEADER START
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* GPL HEADER END
*/
#ifndef _ASM_X86_APICDEF_H
#define _ASM_X86_APICDEF_H

/*
* Constants for various Intel APICs. (local APIC, IOAPIC, etc.)
*
* Alan Cox <Alan.Cox@linux.org>, 1995.
* Ingo Molnar <mingo@redhat.com>, 1999, 2000
* Joyent, Inc. 2011
*/

#define IO_APIC_DEFAULT_PHYS_BASE 0xfec00000
#define APIC_DEFAULT_PHYS_BASE 0xfee00000

/*
* This is the IO-APIC register space as specified
* by Intel docs:
*/
#define IO_APIC_SLOT_SIZE 1024

#define APIC_ID 0x20

#define APIC_LVR 0x30
#define APIC_LVR_MASK 0xFF00FF
#define APIC_LVR_DIRECTED_EOI (1 << 24)
#define GET_APIC_VERSION(x) ((x) & 0xFFu)
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFFu)
#define APIC_INTEGRATED(x) (1)
#define APIC_XAPIC(x) ((x) >= 0x14)
#define APIC_EXT_SPACE(x) ((x) & 0x80000000)
#define APIC_TASKPRI 0x80
#define APIC_TPRI_MASK 0xFFu
#define APIC_ARBPRI 0x90
#define APIC_ARBPRI_MASK 0xFFu
#define APIC_PROCPRI 0xA0
#define APIC_EOI 0xB0
#define APIC_EIO_ACK 0x0
#define APIC_RRR 0xC0
#define APIC_LDR 0xD0
#define APIC_LDR_MASK (0xFFu << 24)
#define GET_APIC_LOGICAL_ID(x) (((x) >> 24) & 0xFFu)
#define SET_APIC_LOGICAL_ID(x) (((x) << 24))
#define APIC_ALL_CPUS 0xFFu
#define APIC_DFR 0xE0
#define APIC_DFR_CLUSTER 0x0FFFFFFFul
#define APIC_DFR_FLAT 0xFFFFFFFFul
#define APIC_SPIV 0xF0
#define APIC_SPIV_DIRECTED_EOI (1 << 12)
#define APIC_SPIV_FOCUS_DISABLED (1 << 9)
#define APIC_SPIV_APIC_ENABLED (1 << 8)
#define APIC_ISR 0x100
#define APIC_ISR_NR 0x8 /* Number of 32 bit ISR registers. */
#define APIC_TMR 0x180
#define APIC_IRR 0x200
#define APIC_ESR 0x280
#define APIC_ESR_SEND_CS 0x00001
#define APIC_ESR_RECV_CS 0x00002
#define APIC_ESR_SEND_ACC 0x00004
#define APIC_ESR_RECV_ACC 0x00008
#define APIC_ESR_SENDILL 0x00020
#define APIC_ESR_RECVILL 0x00040
#define APIC_ESR_ILLREGA 0x00080
#define APIC_LVTCMCI 0x2f0
#define APIC_ICR 0x300
#define APIC_DEST_SELF 0x40000
#define APIC_DEST_ALLINC 0x80000
#define APIC_DEST_ALLBUT 0xC0000
#define APIC_ICR_RR_MASK 0x30000
#define APIC_ICR_RR_INVALID 0x00000
#define APIC_ICR_RR_INPROG 0x10000
#define APIC_ICR_RR_VALID 0x20000
#define APIC_INT_LEVELTRIG 0x08000
#define APIC_INT_ASSERT 0x04000
#define APIC_ICR_BUSY 0x01000
#define APIC_DEST_LOGICAL 0x00800
#define APIC_DEST_PHYSICAL 0x00000
#define APIC_DM_FIXED 0x00000
#define APIC_DM_LOWEST 0x00100
#define APIC_DM_SMI 0x00200
#define APIC_DM_REMRD 0x00300
#define APIC_DM_NMI 0x00400
#define APIC_DM_INIT 0x00500
#define APIC_DM_STARTUP 0x00600
#define APIC_DM_EXTINT 0x00700
#define APIC_VECTOR_MASK 0x000FF
#define APIC_ICR2 0x310
#define GET_APIC_DEST_FIELD(x) (((x) >> 24) & 0xFF)
#define SET_APIC_DEST_FIELD(x) ((x) << 24)
#define APIC_LVTT 0x320
#define APIC_LVTTHMR 0x330
#define APIC_LVTPC 0x340
#define APIC_LVT0 0x350
#define APIC_LVT_TIMER_BASE_MASK (0x3 << 18)
#define GET_APIC_TIMER_BASE(x) (((x) >> 18) & 0x3)
#define SET_APIC_TIMER_BASE(x) (((x) << 18))
#define APIC_TIMER_BASE_CLKIN 0x0
#define APIC_TIMER_BASE_TMBASE 0x1
#define APIC_TIMER_BASE_DIV 0x2
#define APIC_LVT_TIMER_PERIODIC (1 << 17)
#define APIC_LVT_MASKED (1 << 16)
#define APIC_LVT_LEVEL_TRIGGER (1 << 15)
#define APIC_LVT_REMOTE_IRR (1 << 14)
#define APIC_INPUT_POLARITY (1 << 13)
#define APIC_SEND_PENDING (1 << 12)
#define APIC_MODE_MASK 0x700
#define GET_APIC_DELIVERY_MODE(x) (((x) >> 8) & 0x7)
#define SET_APIC_DELIVERY_MODE(x, y) (((x) & ~0x700) | ((y) << 8))
#define APIC_MODE_FIXED 0x0
#define APIC_MODE_NMI 0x4
#define APIC_MODE_EXTINT 0x7
#define APIC_LVT1 0x360
#define APIC_LVTERR 0x370
#define APIC_TMICT 0x380
#define APIC_TMCCT 0x390
#define APIC_TDCR 0x3E0
#define APIC_SELF_IPI 0x3F0
#define APIC_TDR_DIV_TMBASE (1 << 2)
#define APIC_TDR_DIV_1 0xB
#define APIC_TDR_DIV_2 0x0
#define APIC_TDR_DIV_4 0x1
#define APIC_TDR_DIV_8 0x2
#define APIC_TDR_DIV_16 0x3
#define APIC_TDR_DIV_32 0x8
#define APIC_TDR_DIV_64 0x9
#define APIC_TDR_DIV_128 0xA
#define APIC_EFEAT 0x400
#define APIC_ECTRL 0x410
#define APIC_EILVTn(n) (0x500 + 0x10 * n)
#define APIC_EILVT_NR_AMD_K8 1 /* # of extended interrupts */
#define APIC_EILVT_NR_AMD_10H 4
#define APIC_EILVT_LVTOFF(x) (((x) >> 4) & 0xF)
#define APIC_EILVT_MSG_FIX 0x0
#define APIC_EILVT_MSG_SMI 0x2
#define APIC_EILVT_MSG_NMI 0x4
#define APIC_EILVT_MSG_EXT 0x7
#define APIC_EILVT_MASKED (1 << 16)

#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
#define APIC_BASE_MSR 0x800
#define X2APIC_ENABLE (1UL << 10)

#define MAX_IO_APICS 128
#define MAX_LOCAL_APIC 32768

/*
* All x86-64 systems are xAPIC compatible.
* In the following, "apicid" is a physical APIC ID.
*/
#define XAPIC_DEST_CPUS_SHIFT 4
#define XAPIC_DEST_CPUS_MASK ((1u << XAPIC_DEST_CPUS_SHIFT) - 1)
#define XAPIC_DEST_CLUSTER_MASK (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT)
#define APIC_CLUSTER(apicid) ((apicid) & XAPIC_DEST_CLUSTER_MASK)
#define APIC_CLUSTERID(apicid) (APIC_CLUSTER(apicid) >> XAPIC_DEST_CPUS_SHIFT)
#define APIC_CPUID(apicid) ((apicid) & XAPIC_DEST_CPUS_MASK)
#define NUM_APIC_CLUSTERS ((BAD_APICID + 1) >> XAPIC_DEST_CPUS_SHIFT)

/*
* the local APIC register structure, memory mapped. Not terribly well
* tested, but we might eventually use this one in the future - the
* problem why we cannot use it right now is the P5 APIC, it has an
* errata which cannot take 8-bit reads and writes, only 32-bit ones ...
*/
#define uint32_t unsigned int

struct local_apic {

/*000*/ struct { uint32_t __reserved[4]; } __reserved_01;

/*010*/ struct { uint32_t __reserved[4]; } __reserved_02;

/*020*/ struct { /* APIC ID Register */
uint32_t __reserved_1 : 24,
phys_apic_id : 4,
__reserved_2 : 4;
uint32_t __reserved[3];
} id;

/*030*/ const
struct { /* APIC Version Register */
uint32_t version : 8,
__reserved_1 : 8,
max_lvt : 8,
__reserved_2 : 8;
uint32_t __reserved[3];
} version;

/*040*/ struct { uint32_t __reserved[4]; } __reserved_03;

/*050*/ struct { uint32_t __reserved[4]; } __reserved_04;

/*060*/ struct { uint32_t __reserved[4]; } __reserved_05;

/*070*/ struct { uint32_t __reserved[4]; } __reserved_06;

/*080*/ struct { /* Task Priority Register */
uint32_t priority : 8,
__reserved_1 : 24;
uint32_t __reserved_2[3];
} tpr;

/*090*/ const
struct { /* Arbitration Priority Register */
uint32_t priority : 8,
__reserved_1 : 24;
uint32_t __reserved_2[3];
} apr;

/*0A0*/ const
struct { /* Processor Priority Register */
uint32_t priority : 8,
__reserved_1 : 24;
uint32_t __reserved_2[3];
} ppr;

/*0B0*/ struct { /* End Of Interrupt Register */
uint32_t eoi;
uint32_t __reserved[3];
} eoi;

/*0C0*/ struct { uint32_t __reserved[4]; } __reserved_07;

/*0D0*/ struct { /* Logical Destination Register */
uint32_t __reserved_1 : 24,
logical_dest : 8;
uint32_t __reserved_2[3];
} ldr;

/*0E0*/ struct { /* Destination Format Register */
uint32_t __reserved_1 : 28,
model : 4;
uint32_t __reserved_2[3];
} dfr;

/*0F0*/ struct { /* Spurious Interrupt Vector Register */
uint32_t spurious_vector : 8,
apic_enabled : 1,
focus_cpu : 1,
__reserved_2 : 22;
uint32_t __reserved_3[3];
} svr;

/*100*/ struct { /* In Service Register */
/*170*/ uint32_t bitfield;
uint32_t __reserved[3];
} isr [8];

/*180*/ struct { /* Trigger Mode Register */
/*1F0*/ uint32_t bitfield;
uint32_t __reserved[3];
} tmr [8];

/*200*/ struct { /* Interrupt Request Register */
/*270*/ uint32_t bitfield;
uint32_t __reserved[3];
} irr [8];

/*280*/ union { /* Error Status Register */
struct {
uint32_t send_cs_error : 1,
receive_cs_error : 1,
send_accept_error : 1,
receive_accept_error : 1,
__reserved_1 : 1,
send_illegal_vector : 1,
receive_illegal_vector : 1,
illegal_register_address : 1,
__reserved_2 : 24;
uint32_t __reserved_3[3];
} error_bits;
struct {
uint32_t errors;
uint32_t __reserved_3[3];
} all_errors;
} esr;

/*290*/ struct { uint32_t __reserved[4]; } __reserved_08;

/*2A0*/ struct { uint32_t __reserved[4]; } __reserved_09;

/*2B0*/ struct { uint32_t __reserved[4]; } __reserved_10;

/*2C0*/ struct { uint32_t __reserved[4]; } __reserved_11;

/*2D0*/ struct { uint32_t __reserved[4]; } __reserved_12;

/*2E0*/ struct { uint32_t __reserved[4]; } __reserved_13;

/*2F0*/ struct { uint32_t __reserved[4]; } __reserved_14;

/*300*/ struct { /* Interrupt Command Register 1 */
uint32_t vector : 8,
delivery_mode : 3,
destination_mode : 1,
delivery_status : 1,
__reserved_1 : 1,
level : 1,
trigger : 1,
__reserved_2 : 2,
shorthand : 2,
__reserved_3 : 12;
uint32_t __reserved_4[3];
} icr1;

/*310*/ struct { /* Interrupt Command Register 2 */
union {
uint32_t __reserved_1 : 24,
phys_dest : 4,
__reserved_2 : 4;
uint32_t __reserved_3 : 24,
logical_dest : 8;
} dest;
uint32_t __reserved_4[3];
} icr2;

/*320*/ struct { /* LVT - Timer */
uint32_t vector : 8,
__reserved_1 : 4,
delivery_status : 1,
__reserved_2 : 3,
mask : 1,
timer_mode : 1,
__reserved_3 : 14;
uint32_t __reserved_4[3];
} lvt_timer;

/*330*/ struct { /* LVT - Thermal Sensor */
uint32_t vector : 8,
delivery_mode : 3,
__reserved_1 : 1,
delivery_status : 1,
__reserved_2 : 3,
mask : 1,
__reserved_3 : 15;
uint32_t __reserved_4[3];
} lvt_thermal;

/*340*/ struct { /* LVT - Performance Counter */
uint32_t vector : 8,
delivery_mode : 3,
__reserved_1 : 1,
delivery_status : 1,
__reserved_2 : 3,
mask : 1,
__reserved_3 : 15;
uint32_t __reserved_4[3];
} lvt_pc;

/*350*/ struct { /* LVT - LINT0 */
uint32_t vector : 8,
delivery_mode : 3,
__reserved_1 : 1,
delivery_status : 1,
polarity : 1,
remote_irr : 1,
trigger : 1,
mask : 1,
__reserved_2 : 15;
uint32_t __reserved_3[3];
} lvt_lint0;

/*360*/ struct { /* LVT - LINT1 */
uint32_t vector : 8,
delivery_mode : 3,
__reserved_1 : 1,
delivery_status : 1,
polarity : 1,
remote_irr : 1,
trigger : 1,
mask : 1,
__reserved_2 : 15;
uint32_t __reserved_3[3];
} lvt_lint1;

/*370*/ struct { /* LVT - Error */
uint32_t vector : 8,
__reserved_1 : 4,
delivery_status : 1,
__reserved_2 : 3,
mask : 1,
__reserved_3 : 15;
uint32_t __reserved_4[3];
} lvt_error;

/*380*/ struct { /* Timer Initial Count Register */
uint32_t initial_count;
uint32_t __reserved_2[3];
} timer_icr;

/*390*/ const
struct { /* Timer Current Count Register */
uint32_t curr_count;
uint32_t __reserved_2[3];
} timer_ccr;

/*3A0*/ struct { uint32_t __reserved[4]; } __reserved_16;

/*3B0*/ struct { uint32_t __reserved[4]; } __reserved_17;

/*3C0*/ struct { uint32_t __reserved[4]; } __reserved_18;

/*3D0*/ struct { uint32_t __reserved[4]; } __reserved_19;

/*3E0*/ struct { /* Timer Divide Configuration Register */
uint32_t divisor : 4,
__reserved_1 : 28;
uint32_t __reserved_2[3];
} timer_dcr;

/*3F0*/ struct { uint32_t __reserved[4]; } __reserved_20;

} __attribute__ ((packed));

typedef struct local_apic local_apic_t;

#undef uint32_t

#define BAD_APICID 0xFFFFu
#endif /* _ASM_X86_APICDEF_H */
Something went wrong with that request. Please try again.