/* * */ #pragma once #define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */ /* APIC Register Address Map */ #define APIC_ID 0x0020 /* Local APIC ID Register (R/W) */ #define APIC_VER 0x0030 /* Local APIC Version Register (R) */ #define APIC_TPR 0x0080 /* Task Priority Register (R/W) */ #define APIC_APR 0x0090 /* Arbitration Priority Register (R) */ #define APIC_PPR 0x00A0 /* Processor Priority Register (R) */ #define APIC_EOI 0x00B0 /* EOI Register (W) */ #define APIC_LDR 0x00D0 /* Logical Destination Register (R/W) */ #define APIC_DFR 0x00E0 /* Destination Format Register (0-27 R, 28-31 R/W) */ #define APIC_SIVR 0x00F0 /* Spurious Interrupt Vector Register (0-3 R, 4-9 R/W) */ #define APIC_ISR 0x0100 /* Interrupt Service Register 0-255 (R) */ #define APIC_TMR 0x0180 /* Trigger Mode Register 0-255 (R) */ #define APIC_IRR 0x0200 /* Interrupt Request Register 0-255 (r) */ #define APIC_ESR 0x0280 /* Error Status Register (R) */ #define APIC_ICR0 0x0300 /* Interrupt Command Register 0-31 (R/W) */ #define APIC_ICR1 0x0310 /* Interrupt Command Register 32-63 (R/W) */ #define APIC_LVTT 0x0320 /* Local Vector Table (Timer) (R/W) */ #define APIC_LVTTHMR 0x0330 #define APIC_LVTPC 0x0340 /* Performance Counter LVT (R/W) */ #define APIC_LINT0 0x0350 /* Local Vector Table (LINT0) (R/W) */ #define APIC_LINT1 0x0360 /* Local Vector Table (LINT1) (R/W) */ #define APIC_LVT3 0x0370 /* Local Vector Table (Error) (R/W) */ #define APIC_ICRT 0x0380 /* Initial Count Register for Timer (R/W) */ #define APIC_CCRT 0x0390 /* Current Count Register for Timer (R) */ #define APIC_TDCR 0x03E0 /* Timer Divide Configuration Register (R/W) */ #define APIC_ID_MASK (0xF << 24) #define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24) #define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF) #define APIC_VER_MASK 0xFF00FF #define GET_APIC_VERSION(x) ((x) & 0xFF) #define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF) #define APIC_TPR_PRI 0xFF #define APIC_TPR_INT 0xF0 #define APIC_TPR_SUB 0xF #define APIC_TPR_MAX 0xFF /* Maximum priority */ #define APIC_TPR_MIN 0x20 /* Minimum priority */ #define APIC_LDR_MASK (0xFF << 24) #define APIC_SIVR_ENABLE (0x1 << 8) #define APIC_SIVR_FOCUS (0x1 << 9) #define APIC_ESR_MASK (0xFE << 0) /* Error Mask */ #define APIC_ICR0_VECTOR (0xFF << 0) /* Vector */ #define APIC_ICR0_DM (0x7 << 8) /* Delivery Mode */ #define APIC_ICR0_DESTM (0x1 << 11) /* Destination Mode */ #define APIC_ICR0_DS (0x1 << 12) /* Delivery Status */ #define APIC_ICR0_LEVEL (0x1 << 14) /* Level */ #define APIC_ICR0_TM (0x1 << 15) /* Trigger Mode */ #define APIC_ICR0_DESTS (0x3 << 18) /* Destination Shorthand */ /* Delivery Modes */ #define APIC_DM_FIXED (0x0 << 8) #define APIC_DM_LOWEST (0x1 << 8) #define APIC_DM_SMI (0x2 << 8) #define APIC_DM_REMRD (0x3 << 8) #define APIC_DM_NMI (0x4 << 8) #define APIC_DM_INIT (0x5 << 8) #define APIC_DM_STARTUP (0x6 << 8) #define APIC_DM_EXTINT (0x7 << 8) #define GET_APIC_DELIVERY_MODE(x) (((x) >> 8) & 0x7) #define SET_APIC_DELIVERY_MODE(x,y) (((x) & ~0x700) | ((y) << 8)) /* Destination Shorthand values */ #define APIC_ICR0_DESTS_FIELD (0x0 << 0) #define APIC_ICR0_DESTS_SELF (0x1 << 18) #define APIC_ICR0_DESTS_ALL (0x2 << 18) #define APIC_ICR0_DESTS_ALL_BUT_SELF (0x3 << 18) #define APIC_ICR0_LEVEL_DEASSERT (0x0 << 14) /* Deassert level */ #define APIC_ICR0_LEVEL_ASSERT (0x1 << 14) /* Assert level */ #define GET_APIC_DEST_FIELD(x) (((x) >> 24) & 0xFF) #define SET_APIC_DEST_FIELD(x) (((x) & 0xFF) << 24) #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_VECTOR (0xFF << 0) /* Vector */ #define APIC_LVT_DS (0x1 << 12) /* Delivery Status */ #define APIC_LVT_REMOTE_IRR (0x1 << 14) /* Remote IRR */ #define APIC_LVT_LEVEL_TRIGGER (0x1 << 15) /* Lvel Triggered */ #define APIC_LVT_MASKED (0x1 << 16) /* Mask */ #define APIC_LVT_PERIODIC (0x1 << 17) /* Timer Mode */ #define APIC_LVT3_DM (0x7 << 8) #define APIC_LVT3_IIPP (0x1 << 13) #define APIC_LVT3_TM (0x1 << 15) #define APIC_LVT3_MASKED (0x1 << 16) #define APIC_LVT3_OS (0x1 << 17) #define APIC_TDCR_TMBASE (0x1 << 2) #define APIC_TDCR_MASK 0x0F #define APIC_TDCR_2 0x00 #define APIC_TDCR_4 0x01 #define APIC_TDCR_8 0x02 #define APIC_TDCR_16 0x03 #define APIC_TDCR_32 0x08 #define APIC_TDCR_64 0x09 #define APIC_TDCR_128 0x0A #define APIC_TDCR_1 0x0B #define APIC_LVT_VECTOR (0xFF << 0) /* Vector */ #define APIC_LVT_DS (0x1 << 12) /* Delivery Status */ #define APIC_LVT_REMOTE_IRR (0x1 << 14) /* Remote IRR */ #define APIC_LVT_LEVEL_TRIGGER (0x1 << 15) /* Lvel Triggered */ #define APIC_LVT_MASKED (0x1 << 16) /* Mask */ #define APIC_LVT_PERIODIC (0x1 << 17) /* Timer Mode */ #define APIC_LVT3_DM (0x7 << 8) #define APIC_LVT3_IIPP (0x1 << 13) #define APIC_LVT3_TM (0x1 << 15) #define APIC_LVT3_MASKED (0x1 << 16) #define APIC_LVT3_OS (0x1 << 17) #define APIC_TDCR_TMBASE (0x1 << 2) #define APIC_TDCR_MASK 0x0F #define APIC_TDCR_2 0x00 #define APIC_TDCR_4 0x01 #define APIC_TDCR_8 0x02 #define APIC_TDCR_16 0x03 #define APIC_TDCR_32 0x08 #define APIC_TDCR_64 0x09 #define APIC_TDCR_128 0x0A #define APIC_TDCR_1 0x0B #define APIC_TARGET_SELF 0x100 #define APIC_TARGET_ALL 0x200 #define APIC_TARGET_ALL_BUT_SELF 0x300 #define APIC_INTEGRATED(version) (version & 0xF0) typedef enum { amPIC = 0, /* IMCR and PIC compatibility mode */ amVWIRE /* Virtual Wire compatibility mode */ } APIC_MODE; #ifdef CONFIG_SMP #define MAX_CPU 32 #else #define MAX_CPU 1 #endif /* * Local APIC timer IRQ vector is on a different priority level, * to work around the 'lost local interrupt if more than 2 IRQ * sources per level' errata. */ #define LOCAL_TIMER_VECTOR 0xEF #define IPI_VECTOR 0xFB #define ERROR_VECTOR 0xFE #define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */ /* CPU flags */ #define CPU_USABLE 0x01 /* 1 if the CPU is usable (ie. can be used) */ #define CPU_ENABLED 0x02 /* 1 if the CPU is enabled */ #define CPU_BSP 0x04 /* 1 if the CPU is the bootstrap processor */ #define CPU_TSC 0x08 /* 1 if the CPU has a time stamp counter */ typedef struct _CPU_INFO { UCHAR Flags; /* CPU flags */ UCHAR APICId; /* Local APIC ID */ UCHAR APICVersion; /* Local APIC version */ // UCHAR MaxLVT; /* Number of LVT registers */ ULONG BusSpeed; /* BUS speed */ ULONG CoreSpeed; /* Core speed */ UCHAR Padding[16-12]; /* Padding to 16-byte */ } CPU_INFO, *PCPU_INFO; extern ULONG CPUCount; /* Total number of CPUs */ extern ULONG BootCPU; /* Bootstrap processor */ extern ULONG OnlineCPUs; /* Bitmask of online CPUs */ extern CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */ /* Prototypes */ __inline VOID APICWrite(ULONG Offset, ULONG Value); __inline ULONG APICRead(ULONG Offset); VOID APICSendIPI(ULONG Target, ULONG Mode); VOID APICSetup(VOID); VOID HaliInitBSP(VOID); VOID APICSyncArbIDs(VOID); __inline VOID APICSendEOI(VOID); VOID APICCalibrateTimer(ULONG CPU); VOID HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack); static __inline ULONG ThisCPU(VOID) { return (APICRead(APIC_ID) & APIC_ID_MASK) >> 24; } /* EOF */