2008-10-23 13:26:29 +08:00
|
|
|
#ifndef _ASM_X86_IO_APIC_H
|
|
|
|
#define _ASM_X86_IO_APIC_H
|
2008-01-30 20:30:37 +08:00
|
|
|
|
2008-04-19 22:55:13 +08:00
|
|
|
#include <linux/types.h>
|
2008-01-30 20:30:37 +08:00
|
|
|
#include <asm/mpspec.h>
|
|
|
|
#include <asm/apicdef.h>
|
2008-08-20 11:50:52 +08:00
|
|
|
#include <asm/irq_vectors.h>
|
2012-03-29 00:37:36 +08:00
|
|
|
#include <asm/x86_init.h>
|
2008-01-30 20:30:37 +08:00
|
|
|
/*
|
|
|
|
* Intel IO-APIC support for SMP and UP systems.
|
|
|
|
*
|
|
|
|
* Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar
|
|
|
|
*/
|
|
|
|
|
2008-06-07 23:53:56 +08:00
|
|
|
/* I/O Unit Redirection Table */
|
|
|
|
#define IO_APIC_REDIR_VECTOR_MASK 0x000FF
|
|
|
|
#define IO_APIC_REDIR_DEST_LOGICAL 0x00800
|
|
|
|
#define IO_APIC_REDIR_DEST_PHYSICAL 0x00000
|
|
|
|
#define IO_APIC_REDIR_SEND_PENDING (1 << 12)
|
|
|
|
#define IO_APIC_REDIR_REMOTE_IRR (1 << 14)
|
|
|
|
#define IO_APIC_REDIR_LEVEL_TRIGGER (1 << 15)
|
|
|
|
#define IO_APIC_REDIR_MASKED (1 << 16)
|
|
|
|
|
2008-01-30 20:30:37 +08:00
|
|
|
/*
|
|
|
|
* The structure of the IO-APIC:
|
|
|
|
*/
|
|
|
|
union IO_APIC_reg_00 {
|
|
|
|
u32 raw;
|
|
|
|
struct {
|
|
|
|
u32 __reserved_2 : 14,
|
|
|
|
LTS : 1,
|
|
|
|
delivery_type : 1,
|
|
|
|
__reserved_1 : 8,
|
|
|
|
ID : 8;
|
|
|
|
} __attribute__ ((packed)) bits;
|
|
|
|
};
|
|
|
|
|
|
|
|
union IO_APIC_reg_01 {
|
|
|
|
u32 raw;
|
|
|
|
struct {
|
|
|
|
u32 version : 8,
|
|
|
|
__reserved_2 : 7,
|
|
|
|
PRQ : 1,
|
|
|
|
entries : 8,
|
|
|
|
__reserved_1 : 8;
|
|
|
|
} __attribute__ ((packed)) bits;
|
|
|
|
};
|
|
|
|
|
|
|
|
union IO_APIC_reg_02 {
|
|
|
|
u32 raw;
|
|
|
|
struct {
|
|
|
|
u32 __reserved_2 : 24,
|
|
|
|
arbitration : 4,
|
|
|
|
__reserved_1 : 4;
|
|
|
|
} __attribute__ ((packed)) bits;
|
|
|
|
};
|
|
|
|
|
|
|
|
union IO_APIC_reg_03 {
|
|
|
|
u32 raw;
|
|
|
|
struct {
|
|
|
|
u32 boot_DT : 1,
|
|
|
|
__reserved_1 : 31;
|
|
|
|
} __attribute__ ((packed)) bits;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct IO_APIC_route_entry {
|
|
|
|
__u32 vector : 8,
|
|
|
|
delivery_mode : 3, /* 000: FIXED
|
|
|
|
* 001: lowest prio
|
|
|
|
* 111: ExtINT
|
|
|
|
*/
|
|
|
|
dest_mode : 1, /* 0: physical, 1: logical */
|
|
|
|
delivery_status : 1,
|
|
|
|
polarity : 1,
|
|
|
|
irr : 1,
|
|
|
|
trigger : 1, /* 0: edge, 1: level */
|
|
|
|
mask : 1, /* 0: enabled, 1: disabled */
|
|
|
|
__reserved_2 : 15;
|
|
|
|
|
|
|
|
__u32 __reserved_3 : 24,
|
|
|
|
dest : 8;
|
|
|
|
} __attribute__ ((packed));
|
|
|
|
|
x64, x2apic/intr-remap: IO-APIC support for interrupt-remapping
IO-APIC support in the presence of interrupt-remapping infrastructure.
IO-APIC RTE will be programmed with interrupt-remapping table entry(IRTE)
index and the IRTE will contain information about the vector, cpu destination,
trigger mode etc, which traditionally was present in the IO-APIC RTE.
Introduce a new irq_chip for cleaner irq migration (in the process
context as opposed to the current irq migration in the context of an interrupt.
interrupt-remapping infrastructure will help us achieve this cleanly).
For edge triggered, irq migration is a simple atomic update(of vector
and cpu destination) of IRTE and flush the hardware cache.
For level triggered, we need to modify the io-apic RTE aswell with the update
vector information, along with modifying IRTE with vector and cpu destination.
So irq migration for level triggered is little bit more complex compared to
edge triggered migration. But the good news is, we use the same algorithm
for level triggered migration as we have today, only difference being,
we now initiate the irq migration from process context instead of the
interrupt context.
In future, when we do a directed EOI (combined with cpu EOI broadcast
suppression) to the IO-APIC, level triggered irq migration will also be
as simple as edge triggered migration and we can do the irq migration
with a simple atomic update to IO-APIC RTE.
TBD: some tests/changes needed in the presence of fixup_irqs() for
level triggered irq migration.
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: akpm@linux-foundation.org
Cc: arjan@linux.intel.com
Cc: andi@firstfloor.org
Cc: ebiederm@xmission.com
Cc: jbarnes@virtuousgeek.org
Cc: steiner@sgi.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2008-07-11 02:16:56 +08:00
|
|
|
struct IR_IO_APIC_route_entry {
|
|
|
|
__u64 vector : 8,
|
|
|
|
zero : 3,
|
|
|
|
index2 : 1,
|
|
|
|
delivery_status : 1,
|
|
|
|
polarity : 1,
|
|
|
|
irr : 1,
|
|
|
|
trigger : 1,
|
|
|
|
mask : 1,
|
|
|
|
reserved : 31,
|
|
|
|
format : 1,
|
|
|
|
index : 15;
|
2008-01-30 20:30:37 +08:00
|
|
|
} __attribute__ ((packed));
|
|
|
|
|
2015-04-13 14:11:54 +08:00
|
|
|
struct irq_alloc_info;
|
2015-04-13 14:11:55 +08:00
|
|
|
struct irq_data;
|
2015-04-13 14:11:54 +08:00
|
|
|
|
2015-04-14 10:30:06 +08:00
|
|
|
#define IOAPIC_AUTO -1
|
|
|
|
#define IOAPIC_EDGE 0
|
|
|
|
#define IOAPIC_LEVEL 1
|
|
|
|
|
|
|
|
#define IOAPIC_MASKED 1
|
|
|
|
#define IOAPIC_UNMASKED 0
|
|
|
|
|
|
|
|
#define IOAPIC_POL_HIGH 0
|
|
|
|
#define IOAPIC_POL_LOW 1
|
|
|
|
|
|
|
|
#define IOAPIC_DEST_MODE_PHYSICAL 0
|
|
|
|
#define IOAPIC_DEST_MODE_LOGICAL 1
|
|
|
|
|
2014-06-09 16:19:52 +08:00
|
|
|
#define IOAPIC_MAP_ALLOC 0x1
|
|
|
|
#define IOAPIC_MAP_CHECK 0x2
|
2011-02-24 02:54:53 +08:00
|
|
|
|
2008-01-30 20:30:37 +08:00
|
|
|
#ifdef CONFIG_X86_IO_APIC
|
|
|
|
|
|
|
|
/*
|
|
|
|
* # of IO-APICs and # of IRQ routing registers
|
|
|
|
*/
|
|
|
|
extern int nr_ioapics;
|
|
|
|
|
2011-05-19 07:31:37 +08:00
|
|
|
extern int mpc_ioapic_id(int ioapic);
|
|
|
|
extern unsigned int mpc_ioapic_addr(int ioapic);
|
2008-01-30 20:30:37 +08:00
|
|
|
|
|
|
|
/* # of MP IRQ source entries */
|
|
|
|
extern int mp_irq_entries;
|
|
|
|
|
|
|
|
/* MP IRQ source entries */
|
2009-01-12 20:17:22 +08:00
|
|
|
extern struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
|
2008-01-30 20:30:37 +08:00
|
|
|
|
|
|
|
/* 1 if "noapic" boot option passed */
|
|
|
|
extern int skip_ioapic_setup;
|
|
|
|
|
2008-06-11 22:35:14 +08:00
|
|
|
/* 1 if "noapic" boot option passed */
|
|
|
|
extern int noioapicquirk;
|
|
|
|
|
2008-06-11 22:35:15 +08:00
|
|
|
/* -1 if "noapic" boot option passed */
|
|
|
|
extern int noioapicreroute;
|
|
|
|
|
2015-04-14 10:29:56 +08:00
|
|
|
extern u32 gsi_top;
|
|
|
|
|
2014-10-27 16:12:04 +08:00
|
|
|
extern unsigned long io_apic_irqs;
|
|
|
|
|
|
|
|
#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1 << (x)) & io_apic_irqs))
|
|
|
|
|
2008-01-30 20:30:37 +08:00
|
|
|
/*
|
|
|
|
* If we use the IO-APIC for IRQ routing, disable automatic
|
|
|
|
* assignment of PCI IRQ's.
|
|
|
|
*/
|
|
|
|
#define io_apic_assign_pci_irqs \
|
|
|
|
(mp_irq_entries && !skip_ioapic_setup && io_apic_irqs)
|
|
|
|
|
2012-09-26 18:44:45 +08:00
|
|
|
struct irq_cfg;
|
2009-07-11 00:36:20 +08:00
|
|
|
extern void ioapic_insert_resources(void);
|
2014-10-27 16:12:05 +08:00
|
|
|
extern int arch_early_ioapic_init(void);
|
2008-01-30 20:30:37 +08:00
|
|
|
|
2011-05-19 07:31:33 +08:00
|
|
|
extern int save_ioapic_entries(void);
|
|
|
|
extern void mask_ioapic_entries(void);
|
|
|
|
extern int restore_ioapic_entries(void);
|
2008-07-11 02:16:47 +08:00
|
|
|
|
2009-08-20 15:27:29 +08:00
|
|
|
extern void setup_ioapic_ids_from_mpc(void);
|
2010-11-27 00:50:20 +08:00
|
|
|
extern void setup_ioapic_ids_from_mpc_nocheck(void);
|
2009-07-08 11:01:15 +08:00
|
|
|
|
2014-06-09 16:19:52 +08:00
|
|
|
enum ioapic_domain_type {
|
|
|
|
IOAPIC_DOMAIN_INVALID,
|
|
|
|
IOAPIC_DOMAIN_LEGACY,
|
|
|
|
IOAPIC_DOMAIN_STRICT,
|
|
|
|
IOAPIC_DOMAIN_DYNAMIC,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct device_node;
|
2014-06-09 16:19:58 +08:00
|
|
|
struct irq_domain;
|
2014-06-09 16:19:52 +08:00
|
|
|
struct irq_domain_ops;
|
2014-06-09 16:19:58 +08:00
|
|
|
|
2014-06-09 16:19:52 +08:00
|
|
|
struct ioapic_domain_cfg {
|
|
|
|
enum ioapic_domain_type type;
|
|
|
|
const struct irq_domain_ops *ops;
|
|
|
|
struct device_node *dev;
|
|
|
|
};
|
|
|
|
|
2014-06-09 16:19:39 +08:00
|
|
|
extern int mp_find_ioapic(u32 gsi);
|
|
|
|
extern int mp_find_ioapic_pin(int ioapic, u32 gsi);
|
2015-04-13 14:11:54 +08:00
|
|
|
extern int mp_map_gsi_to_irq(u32 gsi, unsigned int flags,
|
|
|
|
struct irq_alloc_info *info);
|
2014-06-09 16:20:06 +08:00
|
|
|
extern void mp_unmap_irq(int irq);
|
2014-10-27 13:21:43 +08:00
|
|
|
extern int mp_register_ioapic(int id, u32 address, u32 gsi_base,
|
|
|
|
struct ioapic_domain_cfg *cfg);
|
2014-10-27 13:21:46 +08:00
|
|
|
extern int mp_unregister_ioapic(u32 gsi_base);
|
2014-10-27 13:21:47 +08:00
|
|
|
extern int mp_ioapic_registered(u32 gsi_base);
|
2015-04-13 14:11:55 +08:00
|
|
|
extern int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
|
|
|
|
unsigned int nr_irqs, void *arg);
|
|
|
|
extern void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq,
|
|
|
|
unsigned int nr_irqs);
|
|
|
|
extern void mp_irqdomain_activate(struct irq_domain *domain,
|
|
|
|
struct irq_data *irq_data);
|
|
|
|
extern void mp_irqdomain_deactivate(struct irq_domain *domain,
|
|
|
|
struct irq_data *irq_data);
|
|
|
|
extern int mp_irqdomain_ioapic_idx(struct irq_domain *domain);
|
2015-04-13 14:11:54 +08:00
|
|
|
extern void ioapic_set_alloc_attr(struct irq_alloc_info *info,
|
|
|
|
int node, int trigger, int polarity);
|
2009-07-08 11:01:15 +08:00
|
|
|
|
2010-11-19 11:33:35 +08:00
|
|
|
extern void mp_save_irq(struct mpc_intsrc *m);
|
|
|
|
|
2011-02-22 22:38:05 +08:00
|
|
|
extern void disable_ioapic_support(void);
|
|
|
|
|
2015-04-24 19:57:48 +08:00
|
|
|
extern void __init io_apic_init_mappings(void);
|
2012-03-29 00:37:36 +08:00
|
|
|
extern unsigned int native_io_apic_read(unsigned int apic, unsigned int reg);
|
2012-09-26 18:44:35 +08:00
|
|
|
extern void native_disable_io_apic(void);
|
2012-03-29 00:37:36 +08:00
|
|
|
|
|
|
|
static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
|
|
|
|
{
|
|
|
|
return x86_io_apic_ops.read(apic, reg);
|
|
|
|
}
|
|
|
|
|
2014-10-27 16:12:04 +08:00
|
|
|
extern void setup_IO_APIC(void);
|
|
|
|
extern void enable_IO_APIC(void);
|
|
|
|
extern void disable_IO_APIC(void);
|
|
|
|
extern void setup_ioapic_dest(void);
|
|
|
|
extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin);
|
|
|
|
extern void print_IO_APICs(void);
|
2008-01-30 20:30:37 +08:00
|
|
|
#else /* !CONFIG_X86_IO_APIC */
|
2009-09-19 05:05:47 +08:00
|
|
|
|
2014-10-27 16:12:04 +08:00
|
|
|
#define IO_APIC_IRQ(x) 0
|
2008-01-30 20:30:37 +08:00
|
|
|
#define io_apic_assign_pci_irqs 0
|
2009-08-20 15:27:29 +08:00
|
|
|
#define setup_ioapic_ids_from_mpc x86_init_noop
|
2009-07-11 00:36:20 +08:00
|
|
|
static inline void ioapic_insert_resources(void) { }
|
2014-10-27 16:12:05 +08:00
|
|
|
static inline int arch_early_ioapic_init(void) { return 0; }
|
2014-10-27 16:12:04 +08:00
|
|
|
static inline void print_IO_APICs(void) {}
|
2010-06-09 02:44:32 +08:00
|
|
|
#define gsi_top (NR_IRQS_LEGACY)
|
2010-03-30 16:07:09 +08:00
|
|
|
static inline int mp_find_ioapic(u32 gsi) { return 0; }
|
2015-04-13 14:11:54 +08:00
|
|
|
static inline int mp_map_gsi_to_irq(u32 gsi, unsigned int flags,
|
|
|
|
struct irq_alloc_info *info)
|
|
|
|
{
|
|
|
|
return gsi;
|
|
|
|
}
|
|
|
|
|
2014-06-09 16:20:06 +08:00
|
|
|
static inline void mp_unmap_irq(int irq) { }
|
2009-09-19 05:05:47 +08:00
|
|
|
|
2011-05-19 07:31:33 +08:00
|
|
|
static inline int save_ioapic_entries(void)
|
2011-02-22 22:38:06 +08:00
|
|
|
{
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2011-05-19 07:31:33 +08:00
|
|
|
static inline void mask_ioapic_entries(void) { }
|
|
|
|
static inline int restore_ioapic_entries(void)
|
2011-02-22 22:38:06 +08:00
|
|
|
{
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2015-04-24 19:57:48 +08:00
|
|
|
static inline void mp_save_irq(struct mpc_intsrc *m) { }
|
2011-02-22 22:38:05 +08:00
|
|
|
static inline void disable_ioapic_support(void) { }
|
2015-04-24 19:57:48 +08:00
|
|
|
static inline void io_apic_init_mappings(void) { }
|
2012-03-29 00:37:36 +08:00
|
|
|
#define native_io_apic_read NULL
|
2012-09-26 18:44:35 +08:00
|
|
|
#define native_disable_io_apic NULL
|
2015-01-16 05:22:30 +08:00
|
|
|
|
|
|
|
static inline void setup_IO_APIC(void) { }
|
|
|
|
static inline void enable_IO_APIC(void) { }
|
|
|
|
static inline void setup_ioapic_dest(void) { }
|
|
|
|
|
2007-10-11 17:20:03 +08:00
|
|
|
#endif
|
2008-01-30 20:30:37 +08:00
|
|
|
|
2008-10-23 13:26:29 +08:00
|
|
|
#endif /* _ASM_X86_IO_APIC_H */
|