ReactOS 0.4.16-dev-297-gc569aee
ioapic.c File Reference
#include <hal.h>
#include <debug.h>
Include dependency graph for ioapic.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define default_EISA_trigger(idx)   (EISA_ELCR_Read(IRQMap[idx].SrcBusIrq))
 
#define default_EISA_polarity(idx)   (0)
 
#define default_ISA_trigger(idx)   (0)
 
#define default_ISA_polarity(idx)   (0)
 
#define default_PCI_trigger(idx)   (1)
 
#define default_PCI_polarity(idx)   (1)
 
#define default_MCA_trigger(idx)   (1)
 
#define default_MCA_polarity(idx)   (0)
 

Functions

VOID Disable8259AIrq (ULONG irq)
 
ULONG IOAPICRead (ULONG Apic, ULONG Offset)
 
VOID IOAPICWrite (ULONG Apic, ULONG Offset, ULONG Value)
 
static ULONG EISA_ELCR_Read (ULONG irq)
 
static ULONG IRQPolarity (ULONG idx)
 
static ULONG IRQTrigger (ULONG idx)
 
static ULONG Pin2Irq (ULONG idx, ULONG apic, ULONG pin)
 
static ULONG AssignIrqVector (ULONG irq)
 
static ULONG IOAPICGetIrqEntry (ULONG apic, ULONG pin, ULONG type)
 
VOID IOAPICSetupIrqs (VOID)
 
static VOID IOAPICClearPin (ULONG Apic, ULONG Pin)
 
static VOID IOAPICClear (ULONG Apic)
 
static VOID IOAPICClearAll (VOID)
 
VOID IOAPICEnable (VOID)
 
VOID IOAPICSetupIds (VOID)
 
VOID IOAPICMaskIrq (ULONG Irq)
 
VOID IOAPICUnmaskIrq (ULONG Irq)
 
VOID IOAPICDump (VOID)
 
VOID HaliReconfigurePciInterrupts (VOID)
 

Variables

MP_CONFIGURATION_INTSRC IRQMap [MAX_IRQ_SOURCE]
 
ULONG IRQCount = 0
 
ULONG IrqApicMap [MAX_IRQ_SOURCE]
 
UCHAR BUSMap [MAX_BUS]
 
UCHAR PCIBUSMap [MAX_BUS]
 
IOAPIC_INFO IOAPICMap [MAX_IOAPIC]
 
ULONG IOAPICCount
 
ULONG IRQVectorMap [MAX_IRQ_SOURCE]
 

Macro Definition Documentation

◆ default_EISA_polarity

#define default_EISA_polarity (   idx)    (0)

Definition at line 35 of file ioapic.c.

◆ default_EISA_trigger

#define default_EISA_trigger (   idx)    (EISA_ELCR_Read(IRQMap[idx].SrcBusIrq))

Definition at line 34 of file ioapic.c.

◆ default_ISA_polarity

#define default_ISA_polarity (   idx)    (0)

Definition at line 41 of file ioapic.c.

◆ default_ISA_trigger

#define default_ISA_trigger (   idx)    (0)

Definition at line 40 of file ioapic.c.

◆ default_MCA_polarity

#define default_MCA_polarity (   idx)    (0)

Definition at line 53 of file ioapic.c.

◆ default_MCA_trigger

#define default_MCA_trigger (   idx)    (1)

Definition at line 52 of file ioapic.c.

◆ default_PCI_polarity

#define default_PCI_polarity (   idx)    (1)

Definition at line 47 of file ioapic.c.

◆ default_PCI_trigger

#define default_PCI_trigger (   idx)    (1)

Definition at line 46 of file ioapic.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file ioapic.c.

Function Documentation

◆ AssignIrqVector()

static ULONG AssignIrqVector ( ULONG  irq)
static

Definition at line 237 of file ioapic.c.

238{
239#if 0
240 static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0;
241#endif
243 /* There may already have been assigned a vector for this IRQ */
245 if (vector > 0)
246 {
247 return vector;
248 }
249#if 0
250 if (current_vector > FIRST_SYSTEM_VECTOR)
251 {
252 vector_offset++;
253 current_vector = FIRST_DEVICE_VECTOR + vector_offset;
254 }
255 else if (current_vector == FIRST_SYSTEM_VECTOR)
256 {
257 DPRINT1("Ran out of interrupt sources\n");
258 ASSERT(FALSE);
259 }
260
261 vector = current_vector;
263 current_vector += 8;
264 return vector;
265#else
268 return vector;
269#endif
270}
#define DPRINT1
Definition: precomp.h:8
#define FALSE
Definition: types.h:117
unsigned char irq
Definition: dsp.h:13
#define IRQ2VECTOR(irq)
Definition: halirq.h:27
ULONG IRQVectorMap[MAX_IRQ_SOURCE]
Definition: ioapic.c:27
#define ASSERT(a)
Definition: mode.c:44
uint32_t ULONG
Definition: typedefs.h:59

Referenced by IOAPICSetupIrqs().

◆ Disable8259AIrq()

VOID Disable8259AIrq ( ULONG  irq)

Definition at line 658 of file ioapic.c.

659{
660 UCHAR tmp;
661
662 if (irq >= 8)
663 {
664 tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
665 tmp |= (1 << (irq - 8));
666 WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
667 }
668 else
669 {
670 tmp = READ_PORT_UCHAR((PUCHAR)0x21);
671 tmp |= (1 << irq);
672 WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
673 }
674}
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
unsigned char * PUCHAR
Definition: typedefs.h:53
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by IOAPICSetupIrqs().

◆ EISA_ELCR_Read()

static ULONG EISA_ELCR_Read ( ULONG  irq)
static

Definition at line 66 of file ioapic.c.

67{
68 if (irq < 16)
69 {
70 PUCHAR port = (PUCHAR)(0x4d0 + (irq >> 3));
71 return (READ_PORT_UCHAR(port) >> (irq & 7)) & 1;
72 }
73 DPRINT1("Broken MPtable reports ISA irq %lu\n", irq);
74 return 0;
75}
USHORT port
Definition: uri.c:228

◆ HaliReconfigurePciInterrupts()

VOID HaliReconfigurePciInterrupts ( VOID  )

Definition at line 634 of file ioapic.c.

635{
636 ULONG i;
637
638 for (i = 0; i < IRQCount; i++)
639 {
640 if (BUSMap[IRQMap[i].SrcBusId] == MP_BUS_PCI)
641 {
642 DPRINT("%02lx: IrqType %02x, IrqFlag %04x, SrcBusId %02x"
643 ", SrcBusIrq %02x, DstApicId %02x, DstApicInt %02x\n",
644 i, IRQMap[i].IrqType, IRQMap[i].IrqFlag, IRQMap[i].SrcBusId,
645 IRQMap[i].SrcBusIrq, IRQMap[i].DstApicId, IRQMap[i].DstApicInt);
646
648 IRQMap[i].SrcBusId,
649 (IRQMap[i].SrcBusIrq >> 2) & 0x1f,
650 &IRQMap[i].DstApicInt,
651 0x3c /*PCI_INTERRUPT_LINE*/,
652 1);
653
654 }
655 }
656}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG NTAPI HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: bus.c:123
UCHAR BUSMap[MAX_BUS]
Definition: ioapic.c:21
MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]
Definition: ioapic.c:17
ULONG IRQCount
Definition: ioapic.c:18
#define MP_BUS_PCI
Definition: mps.h:113
@ PCIConfiguration
Definition: miniport.h:93
#define DPRINT
Definition: sndvol32.h:73

◆ IOAPICClear()

static VOID IOAPICClear ( ULONG  Apic)
static

Definition at line 387 of file ioapic.c.

388{
389 ULONG Pin;
390
391 for (Pin = 0; Pin < /*IOAPICMap[Apic].EntryCount*/24; Pin++)
392 {
393 IOAPICClearPin(Apic, Pin);
394 }
395}
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:428
static VOID IOAPICClearPin(ULONG Apic, ULONG Pin)
Definition: ioapic.c:371

Referenced by IOAPICClearAll().

◆ IOAPICClearAll()

static VOID IOAPICClearAll ( VOID  )
static

Definition at line 398 of file ioapic.c.

399{
400 ULONG Apic;
401
402 for (Apic = 0; Apic < IOAPICCount; Apic++)
403 {
404 IOAPICClear(Apic);
405 }
406}
ULONG IOAPICCount
Definition: ioapic.c:25
static VOID IOAPICClear(ULONG Apic)
Definition: ioapic.c:387

Referenced by IOAPICEnable().

◆ IOAPICClearPin()

static VOID IOAPICClearPin ( ULONG  Apic,
ULONG  Pin 
)
static

Definition at line 371 of file ioapic.c.

372{
374
375 DPRINT("IOAPICClearPin(Apic %lu, Pin %lu\n", Apic, Pin);
376 /*
377 * Disable it in the IO-APIC irq-routing table
378 */
379 memset(&Entry, 0, sizeof(Entry));
380 Entry.mask = 1;
381
382 IOAPICWrite(Apic, IOAPIC_REDTBL + 2 * Pin, *(((PULONG)&Entry) + 0));
383 IOAPICWrite(Apic, IOAPIC_REDTBL + 1 + 2 * Pin, *(((PULONG)&Entry) + 1));
384}
#define IOAPIC_REDTBL
Definition: apicp.h:288
VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value)
Definition: ioapic.c:685
#define memset(x, y, z)
Definition: compat.h:39
base of all file and directory entries
Definition: entries.h:83
Definition: ioapic.h:40
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by IOAPICClear().

◆ IOAPICDump()

VOID IOAPICDump ( VOID  )

Definition at line 524 of file ioapic.c.

525{
526 ULONG apic, i;
527 ULONG reg0, reg1, reg2=0;
528
529 DbgPrint("Number of MP IRQ sources: %d.\n", IRQCount);
530 for (i = 0; i < IOAPICCount; i++)
531 {
532 DbgPrint("Number of IO-APIC #%d registers: %d.\n",
534 IOAPICMap[i].EntryCount);
535 }
536
537 /*
538 * We are a bit conservative about what we expect. We have to
539 * know about every hardware change ASAP.
540 */
541 DbgPrint("Testing the IO APIC.......................\n");
542
543 for (apic = 0; apic < IOAPICCount; apic++)
544 {
545 reg0 = IOAPICRead(apic, IOAPIC_ID);
546 reg1 = IOAPICRead(apic, IOAPIC_VER);
547 if (GET_IOAPIC_VERSION(reg1) >= 0x10)
548 {
549 reg2 = IOAPICRead(apic, IOAPIC_ARB);
550 }
551
552 DbgPrint("\n");
553 DbgPrint("IO APIC #%d......\n", IOAPICMap[apic].ApicId);
554 DbgPrint(".... register #00: %08X\n", reg0);
555 DbgPrint("....... : physical APIC id: %02X\n", GET_IOAPIC_ID(reg0));
556 if (reg0 & 0xF0FFFFFF)
557 {
558 DbgPrint(" WARNING: Unexpected IO-APIC\n");
559 }
560
561 DbgPrint(".... register #01: %08X\n", reg1);
562 i = GET_IOAPIC_MRE(reg1);
563
564 DbgPrint("....... : max redirection entries: %04X\n", i);
565 if ((i != 0x0f) && /* older (Neptune) boards */
566 (i != 0x17) && /* typical ISA+PCI boards */
567 (i != 0x1b) && /* Compaq Proliant boards */
568 (i != 0x1f) && /* dual Xeon boards */
569 (i != 0x22) && /* bigger Xeon boards */
570 (i != 0x2E) &&
571 (i != 0x3F))
572 {
573 DbgPrint(" WARNING: Unexpected IO-APIC\n");
574 }
575
576 i = GET_IOAPIC_VERSION(reg1);
577 DbgPrint("....... : IO APIC version: %04X\n", i);
578 if ((i != 0x01) && /* 82489DX IO-APICs */
579 (i != 0x10) && /* oldest IO-APICs */
580 (i != 0x11) && /* Pentium/Pro IO-APICs */
581 (i != 0x13)) /* Xeon IO-APICs */
582 {
583 DbgPrint(" WARNING: Unexpected IO-APIC\n");
584 }
585
586 if (reg1 & 0xFF00FF00)
587 {
588 DbgPrint(" WARNING: Unexpected IO-APIC\n");
589 }
590
591 if (GET_IOAPIC_VERSION(reg1) >= 0x10)
592 {
593 DbgPrint(".... register #02: %08X\n", reg2);
594 DbgPrint("....... : arbitration: %02X\n",
595 GET_IOAPIC_ARB(reg2));
596 if (reg2 & 0xF0FFFFFF)
597 {
598 DbgPrint(" WARNING: Unexpected IO-APIC\n");
599 }
600 }
601
602 DbgPrint(".... IRQ redirection table:\n");
603 DbgPrint(" NR Log Phy Mask Trig IRR Pol"
604 " Stat Dest Deli Vect: \n");
605
606 for (i = 0; i <= GET_IOAPIC_MRE(reg1); i++)
607 {
609
610 *(((PULONG)&entry)+0) = IOAPICRead(apic, 0x10+i*2);
611 *(((PULONG)&entry)+1) = IOAPICRead(apic, 0x11+i*2);
612
613 DbgPrint(" %02x %03X %02X ",
614 i,
615 entry.dest.logical.logical_dest,
616 entry.dest.physical.physical_dest);
617
618 DbgPrint("%C %C %1d %C %C %C %03X %02X\n",
619 (entry.mask == 0) ? 'U' : 'M', // Unmasked/masked
620 (entry.trigger == 0) ? 'E' : 'L', // Edge/level sensitive
621 entry.irr,
622 (entry.polarity == 0) ? 'H' : 'L', // Active high/active low
623 (entry.delivery_status == 0) ? 'I' : 'S', // Idle / send pending
624 (entry.dest_mode == 0) ? 'P' : 'L', // Physical logical
625 entry.delivery_mode,
626 entry.vector);
627 }
628 }
629
630 DbgPrint(".................................... done.\n");
631}
#define IOAPIC_ID
Definition: apicp.h:285
#define IOAPIC_VER
Definition: apicp.h:286
#define IOAPIC_ARB
Definition: apicp.h:287
#define DbgPrint
Definition: hal.h:12
IOAPIC_INFO IOAPICMap[MAX_IOAPIC]
Definition: ioapic.c:24
ULONG IOAPICRead(ULONG Apic, ULONG Offset)
Definition: ioapic.c:676
#define GET_IOAPIC_ID(x)
Definition: ioapic.h:17
#define GET_IOAPIC_ARB(x)
Definition: ioapic.h:26
#define GET_IOAPIC_VERSION(x)
Definition: ioapic.h:21
#define GET_IOAPIC_MRE(x)
Definition: ioapic.h:23
uint32_t entry
Definition: isohybrid.c:63
_Must_inspect_result_ typedef _In_ ULONG ApicId
Definition: iotypes.h:1105

◆ IOAPICEnable()

VOID IOAPICEnable ( VOID  )

Definition at line 409 of file ioapic.c.

410{
411 ULONG i, tmp;
412
413 /* Setup IRQ to vector translation map */
414 memset(&IRQVectorMap, 0, sizeof(IRQVectorMap));
415
416 /*
417 * The number of IO-APIC IRQ registers (== #pins):
418 */
419 for (i = 0; i < IOAPICCount; i++)
420 {
421 tmp = IOAPICRead(i, IOAPIC_VER);
423 }
424
425 /*
426 * Do not trust the IO-APIC being empty at bootup
427 */
429}
static VOID IOAPICClearAll(VOID)
Definition: ioapic.c:398
ULONG EntryCount
Definition: ioapic.h:73

Referenced by HalAllProcessorsStarted().

◆ IOAPICGetIrqEntry()

static ULONG IOAPICGetIrqEntry ( ULONG  apic,
ULONG  pin,
ULONG  type 
)
static

Definition at line 276 of file ioapic.c.

279{
280 ULONG i;
281
282 for (i = 0; i < IRQCount; i++)
283 {
284 if (IRQMap[i].IrqType == type &&
285 (IRQMap[i].DstApicId == IOAPICMap[apic].ApicId || IRQMap[i].DstApicId == MP_APIC_ALL) &&
286 IRQMap[i].DstApicInt == pin)
287 {
288 return i;
289 }
290 }
291 return -1;
292}
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define MP_APIC_ALL
Definition: mps.h:185
Definition: regsvr.c:104

Referenced by IOAPICSetupIrqs().

◆ IOAPICMaskIrq()

VOID IOAPICMaskIrq ( ULONG  Irq)

Definition at line 494 of file ioapic.c.

495{
497 ULONG Apic = IrqApicMap[Irq];
498
499 *(((PULONG)&Entry)+0) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
500 *(((PULONG)&Entry)+1) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq+1);
501 Entry.dest.logical.logical_dest &= ~(1 << KeGetCurrentProcessorNumber());
502 if (Entry.dest.logical.logical_dest == 0)
503 {
504 Entry.mask = 1;
505 }
506 IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq+1, *(((PULONG)&Entry)+1));
507 IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *(((PULONG)&Entry)+0));
508}
ULONG IrqApicMap[MAX_IRQ_SOURCE]
Definition: ioapic.c:19
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:341

Referenced by HalDisableSystemInterrupt().

◆ IOAPICRead()

ULONG IOAPICRead ( ULONG  Apic,
ULONG  Offset 
)

Definition at line 676 of file ioapic.c.

677{
678 PULONG Base;
679
680 Base = (PULONG)IOAPICMap[Apic].ApicAddress;
681 *Base = Offset;
682 return *((PULONG)((ULONG)Base + IOAPIC_IOWIN));
683}
#define IOAPIC_IOWIN
Definition: apicp.h:282
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2451
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101

Referenced by IOAPICDump(), IOAPICEnable(), IOAPICMaskIrq(), IOAPICSetupIds(), and IOAPICUnmaskIrq().

◆ IOAPICSetupIds()

VOID IOAPICSetupIds ( VOID  )

Definition at line 432 of file ioapic.c.

433{
434 ULONG tmp, apic, i;
435 UCHAR old_id;
436
437 /*
438 * Set the IOAPIC ID to the value stored in the MPC table.
439 */
440 for (apic = 0; apic < IOAPICCount; apic++)
441 {
442
443 /* Read the register 0 value */
444 tmp = IOAPICRead(apic, IOAPIC_ID);
445
446 old_id = IOAPICMap[apic].ApicId;
447
448 if (IOAPICMap[apic].ApicId >= 0xf)
449 {
450 DPRINT1("BIOS bug, IO-APIC#%lu ID is %u in the MPC table\n", apic, IOAPICMap[apic].ApicId);
451 IOAPICMap[apic].ApicId = GET_IOAPIC_ID(tmp);
452 DPRINT1(" Fixed up to %u. (Tell your hardware vendor)\n", IOAPICMap[apic].ApicId);
453 }
454
455 /*
456 * We need to adjust the IRQ routing table
457 * if the ID changed.
458 */
459 if (old_id != IOAPICMap[apic].ApicId)
460 {
461 for (i = 0; i < IRQCount; i++)
462 {
463 if (IRQMap[i].DstApicId == old_id)
464 {
466 }
467 }
468 }
469
470 /*
471 * Read the right value from the MPC table and
472 * write it into the ID register.
473 */
474 DPRINT("Changing IO-APIC physical APIC ID to %u\n", IOAPICMap[apic].ApicId);
475
476 tmp &= ~IOAPIC_ID_MASK;
477 tmp |= SET_IOAPIC_ID(IOAPICMap[apic].ApicId);
478
479 IOAPICWrite(apic, IOAPIC_ID, tmp);
480
481 /*
482 * Sanity check
483 */
484 tmp = IOAPICRead(apic, 0);
485 if (GET_IOAPIC_ID(tmp) != IOAPICMap[apic].ApicId)
486 {
487 DPRINT1("Could not set I/O APIC ID!\n");
488 ASSERT(FALSE);
489 }
490 }
491}
#define SET_IOAPIC_ID(x)
Definition: ioapic.h:18
UCHAR ApicId
Definition: ioapic.h:70

Referenced by HalAllProcessorsStarted().

◆ IOAPICSetupIrqs()

VOID IOAPICSetupIrqs ( VOID  )

Definition at line 296 of file ioapic.c.

297{
299 ULONG apic, pin, idx, irq, first_notcon = 1, vector, trigger;
300
301 DPRINT("Init IO_APIC IRQs\n");
302
303 /* Setup IRQ to vector translation map */
304 memset(&IRQVectorMap, 0, sizeof(IRQVectorMap));
305
306 for (apic = 0; apic < IOAPICCount; apic++)
307 {
308 for (pin = 0; pin < IOAPICMap[apic].EntryCount; pin++)
309 {
310 /*
311 * add it to the IO-APIC irq-routing table
312 */
313 memset(&entry,0,sizeof(entry));
314
315 entry.delivery_mode = (APIC_DM_LOWEST >> 8);
316 entry.dest_mode = 1; /* logical delivery */
317 entry.mask = 1; /* disable IRQ */
318 entry.dest.logical.logical_dest = 0;
319
321 if (idx == (ULONG)-1)
322 {
323 if (first_notcon)
324 {
325 DPRINT(" IO-APIC (apicid-pin) %u-%lu\n", IOAPICMap[apic].ApicId, pin);
326 first_notcon = 0;
327 }
328 else
329 {
330 DPRINT(", %u-%lu\n", IOAPICMap[apic].ApicId, pin);
331 }
332 continue;
333 }
334
335 trigger = IRQTrigger(idx);
336 entry.polarity = IRQPolarity(idx);
337
338 if (trigger)
339 {
340 entry.trigger = 1;
341 }
342
343 irq = Pin2Irq(idx, apic, pin);
344
346 entry.vector = vector;
347
348 DPRINT("Vector 0x%.08lx assigned to irq 0x%.02lx\n", vector, irq);
349
350 if (irq == 0)
351 {
352 /* Mask timer IRQ */
353 entry.mask = 1;
354 }
355
356 if ((apic == 0) && (irq < 16))
357 {
359 }
360 IOAPICWrite(apic, IOAPIC_REDTBL+2*pin+1, *(((PULONG)&entry)+1));
361 IOAPICWrite(apic, IOAPIC_REDTBL+2*pin, *(((PULONG)&entry)+0));
362
363 IrqApicMap[irq] = apic;
364
365 DPRINT("Vector %lx, Pin %lx, Irq %lx\n", vector, pin, irq);
366 }
367 }
368}
unsigned int idx
Definition: utils.c:41
static ULONG Pin2Irq(ULONG idx, ULONG apic, ULONG pin)
Definition: ioapic.c:194
static ULONG IOAPICGetIrqEntry(ULONG apic, ULONG pin, ULONG type)
Definition: ioapic.c:276
static ULONG IRQPolarity(ULONG idx)
Definition: ioapic.c:78
static ULONG IRQTrigger(ULONG idx)
Definition: ioapic.c:136
VOID Disable8259AIrq(ULONG irq)
Definition: ioapic.c:658
static ULONG AssignIrqVector(ULONG irq)
Definition: ioapic.c:237
#define INT_VECTORED
Definition: mps.h:163

Referenced by HalAllProcessorsStarted().

◆ IOAPICUnmaskIrq()

VOID IOAPICUnmaskIrq ( ULONG  Irq)

Definition at line 511 of file ioapic.c.

512{
514 ULONG Apic = IrqApicMap[Irq];
515
516 *(((PULONG)&Entry)+0) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
517 *(((PULONG)&Entry)+1) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq+1);
518 Entry.dest.logical.logical_dest |= 1 << KeGetCurrentProcessorNumber();
519 Entry.mask = 0;
520 IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq+1, *(((PULONG)&Entry)+1));
521 IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *(((PULONG)&Entry)+0));
522}

Referenced by HalEnableSystemInterrupt().

◆ IOAPICWrite()

VOID IOAPICWrite ( ULONG  Apic,
ULONG  Offset,
ULONG  Value 
)

Definition at line 685 of file ioapic.c.

686{
687 PULONG Base;
688
689 Base = (PULONG)IOAPICMap[Apic].ApicAddress;
690 *Base = Offset;
692}
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by IOAPICClearPin(), IOAPICMaskIrq(), IOAPICSetupIds(), IOAPICSetupIrqs(), and IOAPICUnmaskIrq().

◆ IRQPolarity()

static ULONG IRQPolarity ( ULONG  idx)
static

Definition at line 78 of file ioapic.c.

79{
80 ULONG bus = IRQMap[idx].SrcBusId;
81 ULONG polarity;
82
83 /*
84 * Determine IRQ line polarity (high active or low active):
85 */
86 switch (IRQMap[idx].IrqFlag & 3)
87 {
88 case 0: /* conforms, ie. bus-type dependent polarity */
89 {
90 switch (BUSMap[bus])
91 {
92 case MP_BUS_ISA: /* ISA pin */
93 polarity = default_ISA_polarity(idx);
94 break;
95
96 case MP_BUS_EISA: /* EISA pin */
97 polarity = default_EISA_polarity(idx);
98 break;
99
100 case MP_BUS_PCI: /* PCI pin */
101 polarity = default_PCI_polarity(idx);
102 break;
103
104 case MP_BUS_MCA: /* MCA pin */
105 polarity = default_MCA_polarity(idx);
106 break;
107
108 default:
109 DPRINT1("Broken BIOS\n");
110 polarity = 1;
111 }
112 }
113 break;
114
115 case 1: /* high active */
116 polarity = 0;
117 break;
118
119 case 2: /* reserved */
120 DPRINT1("Broken BIOS\n");
121 polarity = 1;
122 break;
123
124 case 3: /* low active */
125 polarity = 1;
126 break;
127
128 default: /* invalid */
129 DPRINT1("Broken BIOS\n");
130 polarity = 1;
131 }
132 return polarity;
133}
#define default_EISA_polarity(idx)
Definition: ioapic.c:35
#define default_MCA_polarity(idx)
Definition: ioapic.c:53
#define default_ISA_polarity(idx)
Definition: ioapic.c:41
#define default_PCI_polarity(idx)
Definition: ioapic.c:47
#define MP_BUS_MCA
Definition: mps.h:114
#define MP_BUS_ISA
Definition: mps.h:111
#define MP_BUS_EISA
Definition: mps.h:112

Referenced by IOAPICSetupIrqs().

◆ IRQTrigger()

static ULONG IRQTrigger ( ULONG  idx)
static

Definition at line 136 of file ioapic.c.

137{
138 ULONG bus = IRQMap[idx].SrcBusId;
139 ULONG trigger;
140
141 /*
142 * Determine IRQ trigger mode (edge or level sensitive):
143 */
144 switch ((IRQMap[idx].IrqFlag >> 2) & 3)
145 {
146 case 0: /* conforms, ie. bus-type dependent */
147 {
148 switch (BUSMap[bus])
149 {
150 case MP_BUS_ISA: /* ISA pin */
151 trigger = default_ISA_trigger(idx);
152 break;
153
154 case MP_BUS_EISA: /* EISA pin */
155 trigger = default_EISA_trigger(idx);
156 break;
157
158 case MP_BUS_PCI: /* PCI pin */
159 trigger = default_PCI_trigger(idx);
160 break;
161
162 case MP_BUS_MCA: /* MCA pin */
163 trigger = default_MCA_trigger(idx);
164 break;
165
166 default:
167 DPRINT1("Broken BIOS\n");
168 trigger = 1;
169 }
170 }
171 break;
172
173 case 1: /* edge */
174 trigger = 0;
175 break;
176
177 case 2: /* reserved */
178 DPRINT1("Broken BIOS\n");
179 trigger = 1;
180 break;
181
182 case 3: /* level */
183 trigger = 1;
184 break;
185
186 default: /* invalid */
187 DPRINT1("Broken BIOS\n");
188 trigger = 0;
189 }
190 return trigger;
191}
#define default_ISA_trigger(idx)
Definition: ioapic.c:40
#define default_EISA_trigger(idx)
Definition: ioapic.c:34
#define default_MCA_trigger(idx)
Definition: ioapic.c:52
#define default_PCI_trigger(idx)
Definition: ioapic.c:46

Referenced by IOAPICSetupIrqs().

◆ Pin2Irq()

static ULONG Pin2Irq ( ULONG  idx,
ULONG  apic,
ULONG  pin 
)
static

Definition at line 194 of file ioapic.c.

197{
198 ULONG irq, i;
199 ULONG bus = IRQMap[idx].SrcBusId;
200
201 /*
202 * Debugging check, we are in big trouble if this message pops up!
203 */
204 if (IRQMap[idx].DstApicInt != pin)
205 {
206 DPRINT1("Broken BIOS or MPTABLE parser\n");
207 }
208
209 switch (BUSMap[bus])
210 {
211 case MP_BUS_ISA: /* ISA pin */
212 case MP_BUS_EISA:
213 case MP_BUS_MCA:
215 break;
216
217 case MP_BUS_PCI: /* PCI pin */
218 /*
219 * PCI IRQs are mapped in order
220 */
221 i = irq = 0;
222 while (i < apic)
223 {
225 }
226 irq += pin;
227 break;
228
229 default:
230 DPRINT1("Unknown bus type %lu\n", bus);
231 irq = 0;
232 }
233 return irq;
234}

Referenced by IOAPICSetupIrqs().

Variable Documentation

◆ BUSMap

UCHAR BUSMap[MAX_BUS]

◆ IOAPICCount

ULONG IOAPICCount

◆ IOAPICMap

◆ IrqApicMap

ULONG IrqApicMap[MAX_IRQ_SOURCE]

Definition at line 19 of file ioapic.c.

Referenced by IOAPICMaskIrq(), IOAPICSetupIrqs(), and IOAPICUnmaskIrq().

◆ IRQCount

◆ IRQMap

◆ IRQVectorMap

ULONG IRQVectorMap[MAX_IRQ_SOURCE]

Definition at line 27 of file ioapic.c.

Referenced by AssignIrqVector(), IOAPICEnable(), and IOAPICSetupIrqs().

◆ PCIBUSMap

UCHAR PCIBUSMap[MAX_BUS]

Definition at line 22 of file ioapic.c.

Referenced by HaliMPBusInfo().