3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: hal/halx86/generic/pic.c
5 * PURPOSE: HAL PIC Management and Control Code
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS ********************************************************************/
19 /* FUNCTIONS ******************************************************************/
23 HalpInitializePICs(IN BOOLEAN EnableInterrupts
)
33 /* Save EFlags and disable interrupts */
34 EFlags
= __readeflags();
37 /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
39 Icw1
.OperatingMode
= Cascade
;
40 Icw1
.Interval
= Interval8
;
42 Icw1
.InterruptVectorAddress
= 0; /* This is only used in MCS80/85 mode */
43 __outbyte(PIC1_CONTROL_PORT
, Icw1
.Bits
);
45 /* Set interrupt vector base */
46 Icw2
.Bits
= PRIMARY_VECTOR_BASE
;
47 __outbyte(PIC1_DATA_PORT
, Icw2
.Bits
);
49 /* Connect slave to IRQ 2 */
51 Icw3
.SlaveIrq2
= TRUE
;
52 __outbyte(PIC1_DATA_PORT
, Icw3
.Bits
);
54 /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
56 Icw4
.SystemMode
= New8086Mode
;
57 Icw4
.EoiMode
= NormalEoi
;
58 Icw4
.BufferedMode
= NonBuffered
;
59 Icw4
.SpecialFullyNestedMode
= FALSE
;
60 __outbyte(PIC1_DATA_PORT
, Icw4
.Bits
);
62 /* Mask all interrupts */
63 __outbyte(PIC1_DATA_PORT
, 0xFF);
65 /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
67 Icw1
.OperatingMode
= Cascade
;
68 Icw1
.Interval
= Interval8
;
70 Icw1
.InterruptVectorAddress
= 0; /* This is only used in MCS80/85 mode */
71 __outbyte(PIC2_CONTROL_PORT
, Icw1
.Bits
);
73 /* Set interrupt vector base */
74 Icw2
.Bits
= PRIMARY_VECTOR_BASE
+ 8;
75 __outbyte(PIC2_DATA_PORT
, Icw2
.Bits
);
80 __outbyte(PIC2_DATA_PORT
, Icw3
.Bits
);
82 /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
84 Icw4
.SystemMode
= New8086Mode
;
85 Icw4
.EoiMode
= NormalEoi
;
86 Icw4
.BufferedMode
= NonBuffered
;
87 Icw4
.SpecialFullyNestedMode
= FALSE
;
88 __outbyte(PIC2_DATA_PORT
, Icw4
.Bits
);
90 /* Mask all interrupts */
91 __outbyte(PIC2_DATA_PORT
, 0xFF);
93 /* Read EISA Edge/Level Register for master and slave */
94 Elcr
.Bits
= (__inbyte(EISA_ELCR_SLAVE
) << 8) | __inbyte(EISA_ELCR_MASTER
);
96 /* IRQs 0, 1, 2, 8, and 13 are system-reserved and must be edge */
97 if (!(Elcr
.Master
.Irq0Level
) && !(Elcr
.Master
.Irq1Level
) && !(Elcr
.Master
.Irq2Level
) &&
98 !(Elcr
.Slave
.Irq8Level
) && !(Elcr
.Slave
.Irq13Level
))
100 /* ELCR is as it's supposed to be, save it */
101 HalpEisaELCR
= Elcr
.Bits
;
102 DPRINT1("HAL Detected EISA Interrupt Controller (ELCR: %lx)\n", HalpEisaELCR
);
104 /* Scan for level interrupts */
105 for (i
= 1, j
= 0; j
< 16; i
<<= 1, j
++)
107 /* Warn the user ReactOS does not (and has never) supported this */
108 if (HalpEisaELCR
& i
) DPRINT1("WARNING: IRQ %d is SHARED and LEVEL-SENSITIVE. This is unsupported!\n", j
);
112 /* Restore interrupt state */
113 if (EnableInterrupts
) EFlags
|= EFLAGS_INTERRUPT_MASK
;
114 __writeeflags(EFlags
);