xref: /reactos/hal/halx86/generic/pic.c (revision 64daf542)
1 /*
2  * PROJECT:         ReactOS HAL
3  * LICENSE:         BSD - See COPYING.ARM in the top level directory
4  * PURPOSE:         Generic HAL PIC Management Code shared between APIC and PIC HAL
5  * PROGRAMMERS:     ReactOS Portable Systems Group
6  */
7 
8  /* INCLUDES *******************************************************************/
9 
10 #include <hal.h>
11 #define NDEBUG
12 #include <debug.h>
13 
14  /* FUNCTIONS ******************************************************************/
15 
16 VOID
17 NTAPI
18 HalpInitializeLegacyPICs(VOID)
19 {
20     I8259_ICW1 Icw1;
21     I8259_ICW2 Icw2;
22     I8259_ICW3 Icw3;
23     I8259_ICW4 Icw4;
24 
25     ASSERT(!(__readeflags() & EFLAGS_INTERRUPT_MASK));
26 
27     /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
28     Icw1.NeedIcw4 = TRUE;
29     Icw1.OperatingMode = Cascade;
30     Icw1.Interval = Interval8;
31     Icw1.InterruptMode = EdgeTriggered;
32     Icw1.Init = TRUE;
33     Icw1.InterruptVectorAddress = 0;
34     __outbyte(PIC1_CONTROL_PORT, Icw1.Bits);
35 
36     /* ICW2 - interrupt vector offset */
37     Icw2.Bits = PRIMARY_VECTOR_BASE;
38     __outbyte(PIC1_DATA_PORT, Icw2.Bits);
39 
40     /* Connect slave to IRQ 2 */
41     Icw3.Bits = 0;
42     Icw3.SlaveIrq2 = TRUE;
43     __outbyte(PIC1_DATA_PORT, Icw3.Bits);
44 
45     /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
46     Icw4.SystemMode = New8086Mode;
47     Icw4.EoiMode = NormalEoi;
48     Icw4.BufferedMode = NonBuffered;
49     Icw4.SpecialFullyNestedMode = FALSE;
50     Icw4.Reserved = 0;
51     __outbyte(PIC1_DATA_PORT, Icw4.Bits);
52 
53     /* Mask all interrupts */
54     __outbyte(PIC1_DATA_PORT, 0xFF);
55 
56     /* Initialize ICW1 for slave, interval 8, edge-triggered mode with ICW4 */
57     Icw1.NeedIcw4 = TRUE;
58     Icw1.InterruptMode = EdgeTriggered;
59     Icw1.OperatingMode = Cascade;
60     Icw1.Interval = Interval8;
61     Icw1.Init = TRUE;
62     Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */
63     __outbyte(PIC2_CONTROL_PORT, Icw1.Bits);
64 
65     /* Set interrupt vector base */
66     Icw2.Bits = PRIMARY_VECTOR_BASE + 8;
67     __outbyte(PIC2_DATA_PORT, Icw2.Bits);
68 
69     /* Slave ID */
70     Icw3.Bits = 0;
71     Icw3.SlaveId = 2;
72     __outbyte(PIC2_DATA_PORT, Icw3.Bits);
73 
74     /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
75     Icw4.SystemMode = New8086Mode;
76     Icw4.EoiMode = NormalEoi;
77     Icw4.BufferedMode = NonBuffered;
78     Icw4.SpecialFullyNestedMode = FALSE;
79     Icw4.Reserved = 0;
80     __outbyte(PIC2_DATA_PORT, Icw4.Bits);
81 
82     /* Mask all interrupts */
83     __outbyte(PIC2_DATA_PORT, 0xFF);
84 }
85