/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* Copyright (c) 2010, Intel Corporation.
* All rights reserved.
*/
#ifndef _SYS_APIC_APIC_H
#define _SYS_APIC_APIC_H
#include <sys/psm_types.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/psm_common.h>
/* Local Unit ID register */
/* I/o Unit Version Register */
/* Task Priority register */
/* EOI register */
/* Remote Read register */
/* Logical Destination register */
/* Destination Format register */
/* Spurious Interrupt Vector register */
/* Error Status Register */
/* Interrupt Command registers */
/* Local Interrupt Vector registers */
/* IPL for performance counter interrupts */
/* Initial Count register */
/* Current Count Register */
/* Divider Configuration Register */
/* Various mode for local APIC. Modes are mutually exclusive */
typedef enum apic_mode {
APIC_IS_DISABLED = 0,
} apic_mode_t;
/* x2APIC SELF IPI Register */
/* General x2APIC constants used at various places */
/* IRR register */
/* ISR register */
/* Bit offset of APIC ID in LID_REG, INT_CMD and in DEST_REG */
/*
* Choose between flat and clustered models by writing the following to the
* FORMAT_REG. 82489 DX documentation seemed to suggest that writing 0 will
* disable logical destination mode.
* Does not seem to be in the docs for local APICs on the processors.
*/
/*
* The commands which follow are window selectors written to APIC_IO_REG
*/
#define IS_CLASS_IOAPIC(b, s, p) \
((b) == PCI_CLASS_PERIPH && (s) == PCI_PERIPH_PIC && \
((p) == PCI_PERIPH_PIC_IF_IO_APIC || \
(p) == PCI_PERIPH_PIC_IF_IOX_APIC))
/*
* These macros are used in frequently called routines like
* apic_intr_enter().
*/
/*
* MP floating pointer structure defined in Intel MP Spec 1.1
*/
struct apic_mpfps_hdr {
};
struct apic_mp_cnf_hdr {
};
struct apic_procent {
};
/*
* proc_cpuflags definitions
*/
struct apic_bus {
};
struct apic_io_entry {
};
struct apic_io_intr {
};
/*
* intr_type definitions
*/
/*
* destination APIC ID
*/
/* local vector table */
/* interrupt command register 32-63 */
/* interrupt command register 0-31 */
/* IO & Local APIC Bit Definitions */
/* spurious interrupt vector register */
/*
* Range of the low byte value in apic_tick before starting calibration
*/
/* spurious interrupt vector */
/* special or reserve vectors */
#define APIC_CHECK_RESERVE_VECTORS(v) \
(((v) == T_FASTTRAP) || ((v) == APIC_SPUR_INTR) || \
((v) == T_SYSCALLINT) || ((v) == T_DTRACE_RET))
/* cmos shutdown code for BIOS */
/* define the entry types for BIOS information tables as defined in PC+MP */
#define APIC_CPU_ENTRY 0
/*
* The MP Floating Point structure could be in 1st 1KB of EBDA or last KB
* of system base memory or in ROM between 0xF0000 and 0xFFFFF
*/
/* definitions for apic_irq_table */
/* biggest positive no. to avoid conflict with actual index */
/*
* definitions for MSI Address
*/
/*
* TM is either edge or level.
*/
/*
* definitions for MSI Data
*/
/*
* use to define each irq setup by the apic
*/
typedef struct apic_irq {
/* table */
/*
* IRQ could be shared (in H/W) in which case dip & major will be
* for the one that was last added at this level. We cannot keep a
* linked list as delspl does not tell us which device has just
* been unloaded. For most servers where we are worried about
* performance, interrupt should not be shared & should not be
* a problem. This does not cause any correctness issue - dip is
* used only as an optimisation to avoid going thru all the tables
* in translate IRQ (which is always called twice due to brokenness
* in the way IPLs are determined for devices). major is used only
* to bind interrupts corresponding to the same device on the same
* CPU. Not finding major will just cause it to be potentially bound
* to another CPU.
*/
/* us in this */
} apic_irq_t;
/* Macros to help deal with shared interrupts */
/*
* We align apic_cpus_info at 64-byte cache line boundary. Please make sure we
* don't want the compiler to optimize apic_cpus_info.
*/
#pragma pack(1)
typedef struct apic_cpus_info {
/*
* Fill to make sure each struct is in separate 64-byte cache line.
*/
#pragma pack()
/*
* APIC ops to support various flavors of APIC like APIC and x2APIC.
*/
typedef struct apic_regs_ops {
int (*apic_get_pri)(void);
/*
* interrupt structure for ioapic and msi
*/
typedef struct ioapic_rdt {
} ioapic_rdt_t;
typedef struct msi_regs {
/*
* APIC ops to support intel interrupt remapping
*/
typedef struct apic_intrmap_ops {
int (*apic_intrmap_init)(int);
void (*apic_intrmap_enable)(int);
int, uchar_t);
void (*apic_intrmap_free_entry)(void **);
/*
* Various poweroff methods and ports & bits for them
*/
#define APIC_POWEROFF_NONE 0
/* For RTC */
/* Used by PSM_INTR_OP_GET_INTR to return device information. */
typedef struct {
/* Contains num_devs elements. */
/* Used by PSM_INTR_OP_GET_TYPE to return platform information. */
typedef struct {
/* Masks for avgi_req_flags. */
/* Other flags */
extern int apic_verbose;
/* Flag definitions for apic_verbose */
/* required test to wait until APIC command is sent on the bus */
#define APIC_AV_PENDING_SET() \
apic_ret();
#ifdef DEBUG
extern int apic_debug;
/*
* set apic_restrict_vector to the # of vectors we want to allow per range
* useful in testing shared interrupt logic by setting it to 2 or 3
*/
extern int apic_restrict_vector;
extern int apic_debug_msgbuf[];
extern int apic_debug_msgbufindex;
/*
* Put "int" info into debug buffer. No MP consistency, but light weight.
* Good enough for most debugging.
*/
#define APIC_DEBUG_BUF_PUT(x) \
apic_debug_msgbuf[apic_debug_msgbufindex++] = x; \
if (apic_verbose & APIC_VERBOSE_POWEROFF_FLAG) \
#else /* DEBUG */
#endif /* DEBUG */
extern int apic_error;
/* values which apic_error can take. Not catastrophic, but may help debug */
/*
* ACPI definitions
*/
/* _PIC method arguments */
#define ACPI_PIC_MODE 0
/* APIC error flags we care about */
/* Maximum number of times to retry reprogramming at apic_intr_exit time */
/* Parameter to ioapic_init_intr(): Should ioapic ints be masked? */
#define IOAPIC_NOMASK 0
#define INTR_ROUND_ROBIN_WITH_AFFINITY 0
struct ioapic_reprogram_data {
/* The CPU to which the int will be bound */
int bindcpu;
/* # times the reprogram timeout was called */
unsigned tries;
};
/* The irq # is implicit in the array index: */
extern struct ioapic_reprogram_data apic_reprogram_info[];
extern int apic_probe_common();
extern void apic_init_common();
extern void ioapic_init_intr();
extern void ioapic_disable_redirection();
extern void apic_cleanup_busy();
extern void apic_intr_redistribute();
extern int apic_allocate_irq(int irq);
struct ioapic_reprogram_data *drep);
extern int apic_state(psm_state_request_t *);
extern int apic_check_msi_support();
int type);
int type);
extern int apic_get_vector_intr_info(int vecirq,
extern char *apic_get_apic_type();
extern uint16_t apic_get_apic_version();
extern void x2apic_send_ipi();
extern void apic_ret();
extern int apic_detect_x2apic();
extern void apic_enable_x2apic();
extern int apic_local_mode();
extern void apic_change_eoi();
extern void apic_send_EOI(uint32_t);
extern void apic_send_directed_EOI(uint32_t);
extern int apic_forceload;
extern apic_cpus_info_t *apic_cpus;
#ifdef _MACHDEP
extern cpuset_t apic_cpumask;
#endif
extern uint_t apic_picinit_called;
extern int apic_max_device_irq;
extern int apic_min_device_irq;
extern lock_t apic_ioapic_lock;
extern kmutex_t airq_mutex;
extern int apic_first_avail_irq;
extern int apic_imcrp;
extern int apic_revector_pending;
extern int apic_sample_factor_redistribution;
extern int apic_int_busy_mark;
extern int apic_int_free_mark;
extern int apic_diff_for_redistribution;
extern int apic_poweroff_method;
extern int apic_enable_acpi;
extern int apic_nproc;
extern int apic_max_nproc;
extern int apic_next_bind_cpu;
extern int apic_redistribute_sample_interval;
extern int apic_multi_msi_enable;
extern int apic_sci_vect;
extern int apic_hpet_vect;
extern apic_reg_ops_t *apic_reg_ops;
extern apic_mode_t apic_mode;
extern void x2apic_update_psm();
extern void apic_change_ops();
extern void apic_common_send_ipi(int, int);
extern void apic_set_directed_EOI_handler();
extern int apic_directed_EOI_supported();
extern apic_intrmap_ops_t *apic_vt_ops;
#ifdef __cplusplus
}
#endif
#endif /* _SYS_APIC_APIC_H */