15
15
#include <acpi.h>
16
16
#include <logmsg.h>
17
17
18
- #define IOAPIC_INVALID_ID 0xFFU
19
-
20
18
#define NR_MAX_GSI (CONFIG_MAX_IOAPIC_NUM * CONFIG_MAX_IOAPIC_LINES)
21
19
22
20
static struct gsi_table gsi_table_data [NR_MAX_GSI ];
23
- static uint32_t ioapic_nr_gsi ;
21
+ static uint32_t ioapic_max_nr_gsi ;
24
22
static spinlock_t ioapic_lock ;
25
23
26
24
static union ioapic_rte saved_rte [CONFIG_MAX_IOAPIC_NUM ][CONFIG_MAX_IOAPIC_LINES ];
27
25
28
- /*
29
- * the irq to ioapic pin mapping should extract from ACPI MADT table
30
- * hardcoded here
31
- */
32
- static const uint32_t legacy_irq_to_pin [NR_LEGACY_IRQ ] = {
33
- 2U , /* IRQ0*/
34
- 1U , /* IRQ1*/
35
- 0U , /* IRQ2 connected to Pin0 (ExtInt source of PIC) if existing */
36
- 3U , /* IRQ3*/
37
- 4U , /* IRQ4*/
38
- 5U , /* IRQ5*/
39
- 6U , /* IRQ6*/
40
- 7U , /* IRQ7*/
41
- 8U , /* IRQ8*/
42
- 9U , /* IRQ9*/
43
- 10U , /* IRQ10*/
44
- 11U , /* IRQ11*/
45
- 12U , /* IRQ12*/
46
- 13U , /* IRQ13*/
47
- 14U , /* IRQ14*/
48
- 15U , /* IRQ15*/
49
- };
50
-
51
- static const uint32_t legacy_irq_trigger_mode [NR_LEGACY_IRQ ] = {
52
- IOAPIC_RTE_TRGRMODE_EDGE , /* IRQ0*/
53
- IOAPIC_RTE_TRGRMODE_EDGE , /* IRQ1*/
26
+ static const uint32_t legacy_irq_trigger_mode [NR_LEGACY_PIN ] = {
54
27
IOAPIC_RTE_TRGRMODE_EDGE , /* IRQ2*/
28
+ IOAPIC_RTE_TRGRMODE_EDGE , /* IRQ1*/
29
+ IOAPIC_RTE_TRGRMODE_EDGE , /* IRQ0*/
55
30
IOAPIC_RTE_TRGRMODE_EDGE , /* IRQ3*/
56
31
IOAPIC_RTE_TRGRMODE_EDGE , /* IRQ4*/
57
32
IOAPIC_RTE_TRGRMODE_EDGE , /* IRQ5*/
@@ -87,7 +62,7 @@ static const uint32_t pic_ioapic_pin_map[NR_LEGACY_PIN] = {
87
62
};
88
63
89
64
static struct ioapic_info ioapic_array [CONFIG_MAX_IOAPIC_NUM ];
90
- static uint16_t ioapic_num ;
65
+ static uint8_t ioapic_num ;
91
66
92
67
uint32_t get_pic_pin_from_ioapic_pin (uint32_t pin_index )
93
68
{
@@ -104,12 +79,12 @@ uint32_t get_pic_pin_from_ioapic_pin(uint32_t pin_index)
104
79
void * gsi_to_ioapic_base (uint32_t gsi )
105
80
{
106
81
107
- return gsi_table_data [gsi ].addr ;
82
+ return gsi_table_data [gsi ].ioapic_info . base_addr ;
108
83
}
109
84
110
- uint32_t ioapic_get_nr_gsi (void )
85
+ uint32_t get_max_nr_gsi (void )
111
86
{
112
- return ioapic_nr_gsi ;
87
+ return ioapic_max_nr_gsi ;
113
88
}
114
89
115
90
static void * map_ioapic (uint64_t ioapic_paddr )
@@ -211,7 +186,7 @@ create_rte_for_gsi_irq(uint32_t irq, uint32_t vr)
211
186
212
187
rte .full = 0UL ;
213
188
214
- if (irq < NR_LEGACY_IRQ ) {
189
+ if (irq < NR_LEGACY_PIN ) {
215
190
rte = create_rte_for_legacy_irq (irq , vr );
216
191
} else {
217
192
/* irq default masked, level trig */
@@ -238,7 +213,7 @@ static void ioapic_set_routing(uint32_t gsi, uint32_t vr)
238
213
239
214
ioapic_base = gsi_to_ioapic_base (gsi );
240
215
rte = create_rte_for_gsi_irq (gsi , vr );
241
- ioapic_set_rte_entry (ioapic_base , gsi_table_data [gsi ].pin , rte );
216
+ ioapic_set_rte_entry (ioapic_base , gsi_table_data [gsi ].ioapic_info . pin , rte );
242
217
243
218
if (rte .bits .trigger_mode == IOAPIC_RTE_TRGRMODE_LEVEL ) {
244
219
set_irq_trigger_mode (gsi , true);
@@ -247,62 +222,71 @@ static void ioapic_set_routing(uint32_t gsi, uint32_t vr)
247
222
}
248
223
249
224
dev_dbg (DBG_LEVEL_IRQ , "GSI: irq:%d pin:%hhu rte:%lx" ,
250
- gsi , gsi_table_data [gsi ].pin ,
225
+ gsi , gsi_table_data [gsi ].ioapic_info . pin ,
251
226
rte .full );
252
227
}
253
228
254
- /**
229
+ /*
255
230
* @pre rte != NULL
231
+ * @pre is_ioapic_irq(irq) == true
256
232
*/
257
233
void ioapic_get_rte (uint32_t irq , union ioapic_rte * rte )
258
234
{
259
235
void * addr ;
260
236
261
- if (ioapic_irq_is_gsi (irq )) {
262
- addr = gsi_to_ioapic_base (irq );
263
- ioapic_get_rte_entry (addr , gsi_table_data [irq ].pin , rte );
264
- }
237
+ addr = gsi_to_ioapic_base (irq );
238
+ ioapic_get_rte_entry (addr , gsi_table_data [irq ].ioapic_info .pin , rte );
265
239
}
266
240
241
+ /*
242
+ * @pre is_ioapic_irq(irq) == true
243
+ */
267
244
void ioapic_set_rte (uint32_t irq , union ioapic_rte rte )
268
245
{
269
246
void * addr ;
270
247
271
- if (ioapic_irq_is_gsi (irq )) {
272
- addr = gsi_to_ioapic_base (irq );
273
- ioapic_set_rte_entry (addr , gsi_table_data [irq ].pin , rte );
248
+ addr = gsi_to_ioapic_base (irq );
249
+ ioapic_set_rte_entry (addr , gsi_table_data [irq ].ioapic_info .pin , rte );
274
250
275
- dev_dbg (DBG_LEVEL_IRQ , "GSI: irq:%d pin:%hhu rte:%lx" ,
276
- irq , gsi_table_data [irq ].pin ,
277
- rte .full );
278
- }
251
+ dev_dbg (DBG_LEVEL_IRQ , "GSI: irq:%d pin:%hhu rte:%lx" ,
252
+ irq , gsi_table_data [irq ].ioapic_info .pin ,
253
+ rte .full );
279
254
}
280
255
281
- bool ioapic_irq_is_gsi (uint32_t irq )
256
+ /*
257
+ * Checks if the gsi is valid
258
+ * 1) gsi < NR_MAX_GSI
259
+ * 2) gsi is valid on the platform according to ACPI MADT info
260
+ */
261
+ bool is_gsi_valid (uint32_t gsi )
282
262
{
283
- return irq < ioapic_nr_gsi ;
263
+
264
+ return (gsi < NR_MAX_GSI ) && (gsi_table_data [gsi ].is_valid );
284
265
}
285
266
286
- uint32_t ioapic_irq_to_pin (uint32_t irq )
287
- {
288
- uint32_t ret ;
267
+ /*
268
+ * IO-APIC gsi and irq are identity mapped in ioapic_setup_irqs
269
+ * So #gsi = #irq for ACRN
270
+ */
289
271
290
- if (ioapic_irq_is_gsi (irq )) {
291
- ret = gsi_table_data [irq ].pin ;
292
- } else {
293
- ret = INVALID_INTERRUPT_PIN ;
294
- }
272
+ bool is_ioapic_irq (uint32_t irq )
273
+ {
295
274
296
- return ret ;
275
+ return is_gsi_valid ( irq ) ;
297
276
}
298
277
299
- bool ioapic_is_pin_valid (uint32_t pin )
278
+ /*
279
+ *@pre gsi < NR_MAX_GSI
280
+ *@pre is_gsi_valid(gsi) == true
281
+ */
282
+
283
+ uint32_t gsi_to_ioapic_pin (uint32_t gsi )
300
284
{
301
- return ( pin != INVALID_INTERRUPT_PIN ) ;
285
+ return gsi_table_data [ gsi ]. ioapic_info . pin ;
302
286
}
303
287
304
288
/*
305
- *@pre ioapic_irq_is_gsi (gsi) == true
289
+ *@pre is_gsi_valid (gsi) == true
306
290
*/
307
291
uint32_t ioapic_gsi_to_irq (uint32_t gsi )
308
292
{
@@ -316,23 +300,21 @@ ioapic_irq_gsi_mask_unmask(uint32_t irq, bool mask)
316
300
uint32_t pin ;
317
301
union ioapic_rte rte ;
318
302
319
- if (ioapic_irq_is_gsi (irq )) {
320
- addr = gsi_to_ioapic_base (irq );
321
- pin = gsi_table_data [irq ].pin ;
303
+ addr = gsi_to_ioapic_base (irq );
304
+ pin = gsi_table_data [irq ].ioapic_info .pin ;
322
305
323
- if (addr != NULL ) {
324
- ioapic_get_rte_entry (addr , pin , & rte );
325
- if (mask ) {
326
- rte .bits .intr_mask = IOAPIC_RTE_MASK_SET ;
327
- } else {
328
- rte .bits .intr_mask = IOAPIC_RTE_MASK_CLR ;
329
- }
330
- ioapic_set_rte_entry (addr , pin , rte );
331
- dev_dbg (DBG_LEVEL_PTIRQ , "update: irq:%d pin:%hhu rte:%lx" ,
332
- irq , pin , rte .full );
306
+ if (addr != NULL ) {
307
+ ioapic_get_rte_entry (addr , pin , & rte );
308
+ if (mask ) {
309
+ rte .bits .intr_mask = IOAPIC_RTE_MASK_SET ;
333
310
} else {
334
- dev_dbg ( DBG_LEVEL_PTIRQ , "NULL Address returned from gsi_table_data" ) ;
311
+ rte . bits . intr_mask = IOAPIC_RTE_MASK_CLR ;
335
312
}
313
+ ioapic_set_rte_entry (addr , pin , rte );
314
+ dev_dbg (DBG_LEVEL_PTIRQ , "update: irq:%d pin:%hhu rte:%lx" ,
315
+ irq , pin , rte .full );
316
+ } else {
317
+ dev_dbg (DBG_LEVEL_PTIRQ , "NULL Address returned from gsi_table_data" );
336
318
}
337
319
}
338
320
@@ -364,17 +346,13 @@ ioapic_nr_pins(void *ioapic_base)
364
346
return nr_pins ;
365
347
}
366
348
349
+ /*
350
+ * @pre is_ioapic_irq(irq) == true
351
+ */
367
352
uint8_t ioapic_irq_to_ioapic_id (uint32_t irq )
368
353
{
369
- uint8_t ret ;
370
-
371
- if (ioapic_irq_is_gsi (irq )) {
372
- ret = gsi_table_data [irq ].ioapic_id ;
373
- } else {
374
- ret = IOAPIC_INVALID_ID ;
375
- }
376
354
377
- return ret ;
355
+ return gsi_table_data [ irq ]. ioapic_info . acpi_id ;
378
356
}
379
357
380
358
int32_t init_ioapic_id_info (void )
@@ -385,7 +363,7 @@ int32_t init_ioapic_id_info(void)
385
363
uint32_t nr_pins , gsi ;
386
364
387
365
ioapic_num = parse_madt_ioapic (& ioapic_array [0 ]);
388
- if (ioapic_num <= (uint16_t )CONFIG_MAX_IOAPIC_NUM ) {
366
+ if (ioapic_num <= (uint8_t )CONFIG_MAX_IOAPIC_NUM ) {
389
367
/*
390
368
* Iterate thru all the IO-APICs on the platform
391
369
* Check the number of pins available on each IOAPIC is less
@@ -415,7 +393,7 @@ int32_t init_ioapic_id_info(void)
415
393
*/
416
394
417
395
if (ret == 0 ) {
418
- if (gsi < (uint32_t ) NR_LEGACY_IRQ ) {
396
+ if (gsi < (uint32_t ) NR_LEGACY_PIN ) {
419
397
pr_err ("Total pin count (%x) is less than NR_LEGACY_IRQ!" , gsi );
420
398
ret = - EINVAL ;
421
399
}
@@ -446,16 +424,13 @@ void ioapic_setup_irqs(void)
446
424
addr = map_ioapic (ioapic_array [ioapic_id ].addr );
447
425
448
426
nr_pins = ioapic_array [ioapic_id ].nr_pins ;
427
+ gsi = ioapic_array [ioapic_id ].gsi_base ;
449
428
for (pin = 0U ; pin < nr_pins ; pin ++ ) {
450
- gsi_table_data [gsi ].ioapic_id = ioapic_array [ioapic_id ].id ;
451
- gsi_table_data [gsi ].addr = addr ;
452
-
453
- if (gsi < NR_LEGACY_IRQ ) {
454
- gsi_table_data [gsi ].pin =
455
- legacy_irq_to_pin [gsi ] & 0xffU ;
456
- } else {
457
- gsi_table_data [gsi ].pin = pin ;
458
- }
429
+ gsi_table_data [gsi ].is_valid = true;
430
+ gsi_table_data [gsi ].ioapic_info .acpi_id = ioapic_array [ioapic_id ].id ;
431
+ gsi_table_data [gsi ].ioapic_info .base_addr = addr ;
432
+ gsi_table_data [gsi ].ioapic_info .pin = pin ;
433
+ gsi_table_data [gsi ].ioapic_info .index = ioapic_id ;
459
434
460
435
/* pinned irq before use it */
461
436
if (alloc_irq_num (gsi ) == IRQ_INVALID ) {
@@ -467,7 +442,7 @@ void ioapic_setup_irqs(void)
467
442
/* assign vector for this GSI
468
443
* for legacy irq, reserved vector and never free
469
444
*/
470
- if (gsi < NR_LEGACY_IRQ ) {
445
+ if (gsi < NR_LEGACY_PIN ) {
471
446
vr = alloc_irq_vector (gsi );
472
447
if (vr == VECTOR_INVALID ) {
473
448
pr_err ("failed to alloc VR" );
@@ -484,7 +459,7 @@ void ioapic_setup_irqs(void)
484
459
}
485
460
486
461
/* system max gsi numbers */
487
- ioapic_nr_gsi = gsi ;
462
+ ioapic_max_nr_gsi = gsi ;
488
463
}
489
464
490
465
void suspend_ioapic (void )
0 commit comments