1 #ifndef __ASM_IO_APIC_H
2 #define __ASM_IO_APIC_H
3 
4 #include <asm/types.h>
5 #include <asm/mpspec.h>
6 #include <asm/apicdef.h>
7 #include <asm/fixmap.h>
8 #include <xen/iommu.h>
9 
10 /*
11  * Intel IO-APIC support for SMP and UP systems.
12  *
13  * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar
14  */
15 
16 #define IO_APIC_BASE(idx) \
17 		((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
18 		+ (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
19 
20 #define IO_APIC_ID(idx) (mp_ioapics[idx].mpc_apicid)
21 
22 /* I/O Unit Redirection Table */
23 #define IO_APIC_REDIR_VECTOR_MASK   0x000FF
24 #define IO_APIC_REDIR_DELIV_MODE_MASK 0x00700
25 #define IO_APIC_REDIR_DEST_LOGICAL  0x00800
26 #define IO_APIC_REDIR_DEST_PHYSICAL 0x00000
27 #define IO_APIC_REDIR_SEND_PENDING  (1 << 12)
28 #define IO_APIC_REDIR_REMOTE_IRR    (1 << 14)
29 #define IO_APIC_REDIR_LEVEL_TRIGGER (1 << 15)
30 #define IO_APIC_REDIR_MASKED        (1 << 16)
31 
32 /*
33  * The structure of the IO-APIC:
34  */
35 union IO_APIC_reg_00 {
36     uint32_t raw;
37     struct {
38         unsigned int __reserved_2:14;
39         unsigned int LTS:1;
40         unsigned int delivery_type:1;
41         unsigned int __reserved_1:8;
42         unsigned int ID:8;
43     } bits;
44 };
45 
46 union IO_APIC_reg_01 {
47     uint32_t raw;
48     struct {
49         unsigned int version:8;
50         unsigned int __reserved_2:7;
51         unsigned int PRQ:1;
52         unsigned int entries:8;
53         unsigned int __reserved_1:8;
54     } bits;
55 };
56 
57 union IO_APIC_reg_02 {
58     uint32_t raw;
59     struct {
60         unsigned int __reserved_2:24;
61         unsigned int arbitration:4;
62         unsigned int __reserved_1:4;
63     } bits;
64 };
65 
66 union IO_APIC_reg_03 {
67     uint32_t raw;
68     struct {
69         unsigned int boot_DT:1;
70         unsigned int __reserved_1:31;
71     } bits;
72 };
73 
74 /*
75  * # of IO-APICs and # of IRQ routing registers
76  */
77 extern int nr_ioapics;
78 extern int nr_ioapic_entries[MAX_IO_APICS];
79 
80 enum ioapic_irq_destination_types {
81 	dest_Fixed = 0,
82 	dest_LowestPrio = 1,
83 	dest_SMI = 2,
84 	dest__reserved_1 = 3,
85 	dest_NMI = 4,
86 	dest_INIT = 5,
87 	dest__reserved_2 = 6,
88 	dest_ExtINT = 7
89 };
90 
91 struct IO_APIC_route_entry {
92     unsigned int vector:8;
93     unsigned int delivery_mode:3; /*
94                                    * 000: FIXED
95                                    * 001: lowest prio
96                                    * 111: ExtINT
97                                    */
98     unsigned int dest_mode:1;     /* 0: physical, 1: logical */
99     unsigned int delivery_status:1;
100     unsigned int polarity:1;      /* 0: low, 1: high */
101     unsigned int irr:1;
102     unsigned int trigger:1;       /* 0: edge, 1: level */
103     unsigned int mask:1;          /* 0: enabled, 1: disabled */
104     unsigned int __reserved_2:15;
105 
106     union {
107         struct {
108             unsigned int __reserved_1:24;
109             unsigned int physical_dest:4;
110             unsigned int __reserved_2:4;
111         } physical;
112 
113         struct {
114             unsigned int __reserved_1:24;
115             unsigned int logical_dest:8;
116         } logical;
117 
118         /* used when Interrupt Remapping with EIM is enabled */
119         unsigned int dest32;
120     } dest;
121 };
122 
123 /*
124  * MP-BIOS irq configuration table structures:
125  */
126 
127 /* I/O APIC entries */
128 extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
129 
130 /* Base GSI for this IO APIC */
131 unsigned int io_apic_gsi_base(unsigned int apic);
132 
133 /* Only need to remap ioapic RTE (reg: 10~3Fh) */
134 #define ioapic_reg_remapped(reg) (iommu_intremap && ((reg) >= 0x10))
135 
__io_apic_read(unsigned int apic,unsigned int reg)136 static inline unsigned int __io_apic_read(unsigned int apic, unsigned int reg)
137 {
138 	*IO_APIC_BASE(apic) = reg;
139 	return *(IO_APIC_BASE(apic)+4);
140 }
141 
io_apic_read(unsigned int apic,unsigned int reg)142 static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
143 {
144 	if (ioapic_reg_remapped(reg))
145 		return iommu_read_apic_from_ire(apic, reg);
146 	return __io_apic_read(apic, reg);
147 }
148 
__io_apic_write(unsigned int apic,unsigned int reg,unsigned int value)149 static inline void __io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
150 {
151 	*IO_APIC_BASE(apic) = reg;
152 	*(IO_APIC_BASE(apic)+4) = value;
153 }
154 
io_apic_write(unsigned int apic,unsigned int reg,unsigned int value)155 static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
156 {
157 	if (ioapic_reg_remapped(reg))
158 		return iommu_update_ire_from_apic(apic, reg, value);
159 	__io_apic_write(apic, reg, value);
160 }
161 
162 /*
163  * Re-write a value: to be used for read-modify-write
164  * cycles where the read already set up the index register.
165  */
io_apic_modify(unsigned int apic,unsigned int reg,unsigned int value)166 static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
167 {
168 	if (ioapic_reg_remapped(reg))
169 		return iommu_update_ire_from_apic(apic, reg, value);
170 	*(IO_APIC_BASE(apic)+4) = value;
171 }
172 
173 /* 1 if "noapic" boot option passed */
174 extern bool skip_ioapic_setup;
175 extern bool ioapic_ack_new;
176 extern bool ioapic_ack_forced;
177 
178 extern int io_apic_get_unique_id (int ioapic, int apic_id);
179 extern int io_apic_get_version (int ioapic);
180 extern int io_apic_get_redir_entries (int ioapic);
181 extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low);
182 
183 extern void ioapic_init(void);
184 
185 extern void ioapic_suspend(void);
186 extern void ioapic_resume(void);
187 
188 extern void dump_ioapic_irq_info(void);
189 
190 extern struct IO_APIC_route_entry __ioapic_read_entry(
191     unsigned int apic, unsigned int pin, bool raw);
192 void __ioapic_write_entry(
193     unsigned int apic, unsigned int pin, bool raw,
194     struct IO_APIC_route_entry);
195 
196 extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
197 extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
198 extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
199 extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
200 extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries,
201                                  bool raw);
202 
203 unsigned highest_gsi(void);
204 
205 int ioapic_guest_read( unsigned long physbase, unsigned int reg, u32 *pval);
206 int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 pval);
207 
208 #endif
209