/*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#ifndef _I386_LAPIC_H_
#define _I386_LAPIC_H_
+/*
+ * Legacy mode definitions.
+ * The register offsets are no longer used by XNU - see LAPIC_MMIO_OFFSET().
+ */
#define LAPIC_START 0xFEE00000
#define LAPIC_SIZE 0x00000400
#define LAPIC_LVT_TM_LEVEL 0x08000
#define LAPIC_LVT_MASKED 0x10000
#define LAPIC_LVT_PERIODIC 0x20000
+#define LAPIC_LVT_TSC_DEADLINE 0x40000
+#define LAPIC_LVT_TMR_SHIFT 17
+#define LAPIC_LVT_TMR_MASK 3
#define LAPIC_TIMER_INITIAL_COUNT 0x00000380
#define LAPIC_TIMER_CURRENT_COUNT 0x00000390
#define LAPIC_TIMER_DIVIDE_CONFIG 0x000003E0
#define CPU_NUMBER(r) \
movl %gs:CPU_NUMBER_GS,r
-#define CPU_NUMBER_FROM_LAPIC(r) \
- movl EXT(lapic_id),r; \
- movl 0(r),r; \
- shrl $(LAPIC_ID_SHIFT),r; \
- andl $(LAPIC_ID_MASK),r; \
- movl EXT(lapic_to_cpu)(,r,4),r
-
#ifndef ASSEMBLER
-#include <stdint.h>
-#include <sys/cdefs.h>
-#include <mach/boolean.h>
-#include <mach/kern_return.h>
+typedef enum {
+ ID = 0x02,
+ VERSION = 0x03,
+ TPR = 0x08,
+ APR = 0x09,
+ PPR = 0x0A,
+ EOI = 0x0B,
+ REMOTE_READ = 0x0C,
+ LDR = 0x0D,
+ DFR = 0x0E,
+ SVR = 0x0F,
+ ISR_BASE = 0x10,
+ TMR_BASE = 0x18,
+ IRR_BASE = 0x20,
+ ERROR_STATUS = 0x28,
+ LVT_CMCI = 0x2F,
+ ICR = 0x30,
+ ICRD = 0x31,
+ LVT_TIMER = 0x32,
+ LVT_THERMAL = 0x33,
+ LVT_PERFCNT = 0x34,
+ LVT_LINT0 = 0x35,
+ LVT_LINT1 = 0x36,
+ LVT_ERROR = 0x37,
+ TIMER_INITIAL_COUNT = 0x38,
+ TIMER_CURRENT_COUNT = 0x39,
+ TIMER_DIVIDE_CONFIG = 0x3E,
+} lapic_register_t;
+
+#define LAPIC_MMIO_PBASE 0xFEE00000 /* Default physical MMIO addr */
+#define LAPIC_MMIO_VBASE lapic_vbase /* Actual virtual mapped addr */
+#define LAPIC_MSR_BASE 0x800
+
+#define LAPIC_MMIO_OFFSET(reg) (reg << 4)
+#define LAPIC_MSR_OFFSET(reg) (reg)
+
+#define LAPIC_MMIO(reg) ((volatile uint32_t *) \
+ (LAPIC_MMIO_VBASE + LAPIC_MMIO_OFFSET(reg)))
+#define LAPIC_MSR(reg) (LAPIC_MSR_BASE + LAPIC_MSR_OFFSET(reg))
+
+typedef struct {
+ void (*init) (void);
+ uint32_t (*read) (lapic_register_t);
+ void (*write)(lapic_register_t, uint32_t);
+} lapic_ops_table_t;
+extern lapic_ops_table_t *lapic_ops;
+
+#define LAPIC_WRITE(reg,val) lapic_ops->write(reg, val)
+#define LAPIC_READ(reg) lapic_ops->read(reg)
+#define LAPIC_READ_OFFSET(reg,off) LAPIC_READ((reg)+(off))
+
typedef enum {
periodic,
one_shot
#define LAPIC_NMI_INTERRUPT 0x2
#define LAPIC_FUNC_TABLE_SIZE (LAPIC_PERFCNT_INTERRUPT + 1)
-#define LAPIC_WRITE(reg,val) \
- *((volatile uint32_t *)(lapic_start + LAPIC_##reg)) = (val)
-#define LAPIC_READ(reg) \
- (*((volatile uint32_t *)(lapic_start + LAPIC_##reg)))
-#define LAPIC_READ_OFFSET(reg,off) \
- (*((volatile uint32_t *)(lapic_start + LAPIC_##reg + (off))))
-
#define LAPIC_VECTOR(src) \
(lapic_interrupt_base + LAPIC_##src##_INTERRUPT)
#define LAPIC_ISR_IS_SET(base,src) \
- (LAPIC_READ_OFFSET(ISR_BASE,((base+LAPIC_##src##_INTERRUPT)/32)*0x10) \
+ (LAPIC_READ_OFFSET(ISR_BASE,(base+LAPIC_##src##_INTERRUPT)/32) \
& (1 <<((base + LAPIC_##src##_INTERRUPT)%32)))
-extern vm_offset_t lapic_start;
-
extern void lapic_init(void);
extern void lapic_configure(void);
extern void lapic_shutdown(void);
extern void lapic_smm_restore(void);
extern boolean_t lapic_probe(void);
extern void lapic_dump(void);
+extern void lapic_cpu_map_dump(void);
extern int lapic_interrupt(
int interrupt, x86_saved_state_t *state);
extern void lapic_end_of_interrupt(void);
extern void lapic_unmask_perfcnt_interrupt(void);
+extern void lapic_set_perfcnt_interrupt_mask(boolean_t);
extern void lapic_send_ipi(int cpu, int interupt);
extern int lapic_to_cpu[];
extern int cpu_to_lapic[];
extern int lapic_interrupt_base;
+extern void lapic_cpu_map_init(void);
extern void lapic_cpu_map(int lapic, int cpu_num);
extern uint32_t ml_get_apicid(uint32_t cpu);
extern uint32_t ml_get_cpuid(uint32_t lapic_index);
+extern void lapic_config_timer(
+ boolean_t interrupt,
+ lapic_timer_mode_t mode,
+ lapic_timer_divide_t divisor);
+
+extern void lapic_set_timer_fast(
+ lapic_timer_count_t initial_count);
+
extern void lapic_set_timer(
boolean_t interrupt,
lapic_timer_mode_t mode,
lapic_timer_count_t *initial_count,
lapic_timer_count_t *current_count);
+extern void lapic_config_tsc_deadline_timer(void);
+extern void lapic_set_tsc_deadline_timer(uint64_t deadline);
+extern uint64_t lapic_get_tsc_deadline_timer(void);
+
typedef int (*i386_intr_func_t)(x86_saved_state_t *state);
extern void lapic_set_intr_func(int intr, i386_intr_func_t func);
+extern void lapic_set_pmi_func(i386_intr_func_t);
+
static inline void lapic_set_timer_func(i386_intr_func_t func)
{
lapic_set_intr_func(LAPIC_VECTOR(TIMER), func);
}
-static inline void lapic_set_pmi_func(i386_intr_func_t func)
-{
- lapic_set_intr_func(LAPIC_VECTOR(PERFCNT), func);
-}
+
static inline void lapic_set_thermal_func(i386_intr_func_t func)
{
lapic_set_intr_func(LAPIC_VECTOR(THERMAL), func);
lapic_set_intr_func(LAPIC_VECTOR(PM), func);
}
+extern boolean_t lapic_is_interrupt_pending(void);
+extern boolean_t lapic_is_interrupting(uint8_t vector);
+extern void lapic_interrupt_counts(uint64_t intrs[256]);
+extern void lapic_disable_timer(void);
+
#ifdef MP_DEBUG
+extern void lapic_cpu_map_dump(void);
#define LAPIC_CPU_MAP_DUMP() lapic_cpu_map_dump()
#define LAPIC_DUMP() lapic_dump()
#else