[ros-diffs] [sir_richard] 45180: [HAL]: Initialize the i8259A PIC controllers in C, and add register structures and enumerations to document the bits. These were taken from ISA System Architecture 3rd Edition and EISA System Architecture 2nd Edition by Mindshare. [HAL]: Add code to detect EISA systems with ELCR (Edge/Level Control Register). Since the current HAL does not support these, warn users about any level/shared interrupts, since they are likely to cause trouble.

sir_richard at svn.reactos.org sir_richard at svn.reactos.org
Thu Jan 21 13:51:13 CET 2010


Author: sir_richard
Date: Thu Jan 21 13:51:13 2010
New Revision: 45180

URL: http://svn.reactos.org/svn/reactos?rev=45180&view=rev
Log:
[HAL]: Initialize the i8259A PIC controllers in C, and add register structures and enumerations to document the bits. These were taken from ISA System Architecture 3rd Edition and EISA System Architecture 2nd Edition by Mindshare.
[HAL]: Add code to detect EISA systems with ELCR (Edge/Level Control Register). Since the current HAL does not support these, warn users about any level/shared interrupts, since they are likely to cause trouble.

Added:
    trunk/reactos/hal/halx86/generic/pic.c   (with props)
Modified:
    trunk/reactos/hal/halx86/generic/halinit.c
    trunk/reactos/hal/halx86/generic/irq.S
    trunk/reactos/hal/halx86/hal_generic_up.rbuild
    trunk/reactos/hal/halx86/include/halp.h

Modified: trunk/reactos/hal/halx86/generic/halinit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/halinit.c?rev=45180&r1=45179&r2=45180&view=diff
==============================================================================
--- trunk/reactos/hal/halx86/generic/halinit.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/generic/halinit.c [iso-8859-1] Thu Jan 21 13:51:13 2010
@@ -92,7 +92,7 @@
         }
 
         /* Initialize the PICs */
-        HalpInitPICs();
+        HalpInitializePICs(TRUE);
 
         /* Force initial PIC state */
         KfRaiseIrql(KeGetCurrentIrql());

Modified: trunk/reactos/hal/halx86/generic/irq.S
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/irq.S?rev=45180&r1=45179&r2=45180&view=diff
==============================================================================
--- trunk/reactos/hal/halx86/generic/irq.S [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/generic/irq.S [iso-8859-1] Thu Jan 21 13:51:13 2010
@@ -15,25 +15,6 @@
 .intel_syntax noprefix
 
 /* GLOBALS *******************************************************************/
-
-PICInitTable:
-
-    /* Master PIC */
-    .short 0x20                         /* Port */
-    .byte 0x11                          /* Edge, cascade, CAI 8, ICW4 */
-    .byte PRIMARY_VECTOR_BASE           /* Base */
-    .byte 4                             /* IRQ 4 connected to slave */
-    .byte 1                             /* Non buffered, not nested, 8086 */
-
-    /* Slave PIC */
-    .short 0xA0                         /* Port */
-    .byte 0x11                          /* Edge, cascade, CAI 8, ICW4 */
-    .byte PRIMARY_VECTOR_BASE + 8       /* Base */
-    .byte 2                             /* Slave ID: Slave 2 */
-    .byte 1                             /* Non buffered, not nested, 8086 */
-
-    /* End of initialization table */
-    .short 0
 
 KiI8259MaskTable:
     .long 0                             /* IRQL 0 */
@@ -193,66 +174,6 @@
     ret
 .endfunc
 
-.globl _HalpInitPICs at 0
-.func HalpInitPICs at 0
-_HalpInitPICs at 0:
-
-    /* Save ESI and disable interrupts */
-    push esi
-    pushf
-    cli
-
-    /* Read the init table */
-    lea esi, PICInitTable
-    lodsw
-
-InitLoop:
-
-    /* Put the port in EDX */
-    movzx edx, ax
-
-    /* Initialize the PIC, using a delay for each command */
-    outsb
-    jmp $+2
-    inc edx
-    outsb
-    jmp $+2
-    outsb
-    jmp $+2
-    outsb
-    jmp $+2
-
-    /* Mask all interrupts */
-    mov al, 0xFF
-    out dx, al
-
-    /* Check if we're done, otherwise initialize next PIC */
-    lodsw
-    cmp ax, 0
-    jnz InitLoop
-
-    /* Read EISA Edge/Level Register */
-    mov edx, 0x4D1
-    in al, dx
-    mov ah, al
-    dec edx
-    in al, dx
-
-    /* Clear reserved bits and see if there's anything there */
-    and eax, 0xDEF8
-    cmp eax, 0xDEF8
-    jz NoEisa
-
-    /* FIXME */
-    //UNHANDLED_PATH
-
-/* Restore interrupts and return */
-NoEisa:
-    popf
-    pop esi
-    ret
-.endfunc
-
 .globl @HalClearSoftwareInterrupt at 4
 .func @HalClearSoftwareInterrupt at 4, @HalClearSoftwareInterrupt at 4
 @HalClearSoftwareInterrupt at 4:

Added: trunk/reactos/hal/halx86/generic/pic.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/pic.c?rev=45180&view=auto
==============================================================================
--- trunk/reactos/hal/halx86/generic/pic.c (added)
+++ trunk/reactos/hal/halx86/generic/pic.c [iso-8859-1] Thu Jan 21 13:51:13 2010
@@ -1,0 +1,116 @@
+/*
+ * PROJECT:         ReactOS HAL
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            hal/halx86/generic/pic.c
+ * PURPOSE:         HAL PIC Management and Control Code
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <hal.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+USHORT HalpEisaELCR;
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+HalpInitializePICs(IN BOOLEAN EnableInterrupts)
+{
+    ULONG EFlags;
+    I8259_ICW1 Icw1;
+    I8259_ICW2 Icw2;
+    I8259_ICW3 Icw3;
+    I8259_ICW4 Icw4;
+    EISA_ELCR Elcr;
+    ULONG i, j;
+    
+    /* Save EFlags and disable interrupts */
+    EFlags = __readeflags();
+    _disable();
+    
+    /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
+    Icw1.NeedIcw4 = TRUE;
+    Icw1.OperatingMode = Cascade;
+    Icw1.Interval = Interval8;
+    Icw1.Init = TRUE;
+    Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */
+    __outbyte(PIC1_CONTROL_PORT, Icw1.Bits);
+    
+    /* Set interrupt vector base */
+    Icw2.Bits = PRIMARY_VECTOR_BASE;
+    __outbyte(PIC1_DATA_PORT, Icw2.Bits);
+    
+    /* Connect slave to IRQ 2 */
+    Icw3.Bits = 0;
+    Icw3.SlaveIrq2 = TRUE;
+    __outbyte(PIC1_DATA_PORT, Icw3.Bits);
+    
+    /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
+    Icw4.Reserved = 0;
+    Icw4.SystemMode = New8086Mode;
+    Icw4.EoiMode = NormalEoi;
+    Icw4.BufferedMode = NonBuffered;
+    Icw4.SpecialFullyNestedMode = FALSE;
+    __outbyte(PIC1_DATA_PORT, Icw4.Bits);
+    
+    /* Mask all interrupts */
+    __outbyte(PIC1_DATA_PORT, 0xFF);
+    
+    /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
+    Icw1.NeedIcw4 = TRUE;
+    Icw1.OperatingMode = Cascade;
+    Icw1.Interval = Interval8;
+    Icw1.Init = TRUE;
+    Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */
+    __outbyte(PIC2_CONTROL_PORT, Icw1.Bits);
+    
+    /* Set interrupt vector base */
+    Icw2.Bits = PRIMARY_VECTOR_BASE + 8;
+    __outbyte(PIC2_DATA_PORT, Icw2.Bits);
+    
+    /* Slave ID */
+    Icw3.Bits = 0;
+    Icw3.SlaveId = 2;
+    __outbyte(PIC2_DATA_PORT, Icw3.Bits);
+    
+    /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
+    Icw4.Reserved = 0;
+    Icw4.SystemMode = New8086Mode;
+    Icw4.EoiMode = NormalEoi;
+    Icw4.BufferedMode = NonBuffered;
+    Icw4.SpecialFullyNestedMode = FALSE;
+    __outbyte(PIC2_DATA_PORT, Icw4.Bits);
+    
+    /* Mask all interrupts */
+    __outbyte(PIC2_DATA_PORT, 0xFF);
+    
+    /* Read EISA Edge/Level Register for master and slave */
+    Elcr.Bits = (__inbyte(EISA_ELCR_SLAVE) << 8) | __inbyte(EISA_ELCR_MASTER);
+    
+    /* IRQs 0, 1, 2, 8, and 13 are system-reserved and must be edge */
+    if (!(Elcr.Master.Irq0Level) && !(Elcr.Master.Irq1Level) && !(Elcr.Master.Irq2Level) &&
+        !(Elcr.Slave.Irq8Level) && !(Elcr.Slave.Irq13Level))
+    {
+        /* ELCR is as it's supposed to be, save it */
+        HalpEisaELCR = Elcr.Bits;
+        DPRINT1("HAL Detected EISA Interrupt Controller (ELCR: %lx)\n", HalpEisaELCR);
+        
+        /* Scan for level interrupts */
+        for (i = 1, j = 0; j < 16; i <<= 1, j++)
+        {
+            /* Warn the user ReactOS does not (and has never) supported this */
+            if (HalpEisaELCR & i) DPRINT1("WARNING: IRQ %d is SHARED and LEVEL-SENSITIVE. This is unsupported!\n", j);
+        }
+    }
+    
+    /* Restore interrupt state */
+    if (EnableInterrupts) EFlags |= EFLAGS_INTERRUPT_MASK;
+    __writeeflags(EFlags);
+}
+

Propchange: trunk/reactos/hal/halx86/generic/pic.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/hal/halx86/hal_generic_up.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/hal_generic_up.rbuild?rev=45180&r1=45179&r2=45180&view=diff
==============================================================================
--- trunk/reactos/hal/halx86/hal_generic_up.rbuild [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/hal_generic_up.rbuild [iso-8859-1] Thu Jan 21 13:51:13 2010
@@ -6,6 +6,7 @@
 		<include base="ntoskrnl">include</include>
 		<define name="_NTHAL_" />
 		<directory name="generic">
+            <file>pic.c</file>
 			<file>irq.S</file>
 			<file>processor.c</file>
 			<file>spinlock.c</file>

Modified: trunk/reactos/hal/halx86/include/halp.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/include/halp.h?rev=45180&r1=45179&r2=45180&view=diff
==============================================================================
--- trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] Thu Jan 21 13:51:13 2010
@@ -128,6 +128,161 @@
 } SYSTEM_CONTROL_PORT_B_REGISTER, *PSYSTEM_CONTROL_PORT_B_REGISTER;
 
 //
+// See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
+// P. 396, 397
+//
+// These ports are controlled by the i8259 Programmable Interrupt Controller (PIC)
+//
+#define PIC1_CONTROL_PORT      0x20
+#define PIC1_DATA_PORT         0x21
+#define PIC2_CONTROL_PORT      0xA0
+#define PIC2_DATA_PORT         0xA1
+
+//
+// Definitions for ICW/OCW Bits
+//
+typedef enum _I8259_ICW1_OPERATING_MODE
+{
+    Cascade,
+    Single
+} I8259_ICW1_OPERATING_MODE;
+
+typedef enum _I8259_ICW1_INTERRUPT_MODE
+{
+    EdgeTriggered,
+    LevelTriggered
+} I8259_ICW1_INTERRUPT_MODE;
+
+typedef enum _I8259_ICW1_INTERVAL
+{
+    Interval8,
+    Interval4
+} I8259_ICW1_INTERVAL;
+
+typedef enum _I8259_ICW4_SYSTEM_MODE
+{
+    Mcs8085Mode,
+    New8086Mode
+} I8259_ICW4_SYSTEM_MODE;
+
+typedef enum _I8259_ICW4_EOI_MODE
+{
+    NormalEoi,
+    AutomaticEoi
+} I8259_ICW4_EOI_MODE;
+
+typedef enum _I8259_ICW4_BUFFERED_MODE
+{
+    NonBuffered,
+    NonBuffered2,
+    BufferedSlave,
+    BufferedMaster
+} I8259_ICW4_BUFFERED_MODE;
+
+//
+// Definitions for ICW Registers
+//
+typedef union _I8259_ICW1
+{
+    struct 
+    {
+        UCHAR NeedIcw4:1;
+        I8259_ICW1_OPERATING_MODE OperatingMode:1;
+        I8259_ICW1_INTERVAL Interval:1;
+        I8259_ICW1_INTERRUPT_MODE InterruptMode:1;
+        UCHAR Init:1;
+        UCHAR InterruptVectorAddress:3;
+    };
+    UCHAR Bits;
+} I8259_ICW1, *PI8259_ICW1;
+
+typedef union _I8259_ICW2
+{
+    struct 
+    {
+        UCHAR Sbz:3;
+        UCHAR InterruptVector:5;
+    };
+    UCHAR Bits;
+} I8259_ICW2, *PI8259_ICW2;
+
+typedef union _I8259_ICW3
+{
+    union
+    {
+        struct 
+        {
+            UCHAR SlaveIrq0:1;
+            UCHAR SlaveIrq1:1;
+            UCHAR SlaveIrq2:1;
+            UCHAR SlaveIrq3:1;
+            UCHAR SlaveIrq4:1;
+            UCHAR SlaveIrq5:1;
+            UCHAR SlaveIrq6:1;
+            UCHAR SlaveIrq7:1;
+        };
+        struct 
+        {
+            UCHAR SlaveId:3;
+            UCHAR Reserved:5;
+        };
+    };
+    UCHAR Bits;
+} I8259_ICW3, *PI8259_ICW3;
+
+typedef union _I8259_ICW4
+{
+    struct 
+    {
+        I8259_ICW4_SYSTEM_MODE SystemMode:1;
+        I8259_ICW4_EOI_MODE EoiMode:1;
+        I8259_ICW4_BUFFERED_MODE BufferedMode:2;
+        UCHAR SpecialFullyNestedMode:1;
+        UCHAR Reserved:3;
+    };
+    UCHAR Bits;
+} I8259_ICW4, *PI8259_ICW4;
+
+//
+// See EISA System Architecture 2nd Edition (Tom Shanley, Don Anderson, John Swindle)
+// P. 34, 35
+//
+// These ports are controlled by the i8259A Programmable Interrupt Controller (PIC)
+//
+#define EISA_ELCR_MASTER       0x4D0
+#define EISA_ELCR_SLAVE        0x4D1
+
+typedef union _EISA_ELCR
+{
+    struct
+    {
+        struct
+        {
+            UCHAR Irq0Level:1;
+            UCHAR Irq1Level:1;
+            UCHAR Irq2Level:1;
+            UCHAR Irq3Level:1;
+            UCHAR Irq4Level:1;
+            UCHAR Irq5Level:1;
+            UCHAR Irq6Level:1;
+            UCHAR Irq7Level:1;
+        } Master;
+        struct
+        {
+            UCHAR Irq8Level:1;
+            UCHAR Irq9Level:1;
+            UCHAR Irq10Level:1;
+            UCHAR Irq11Level:1;
+            UCHAR Irq12Level:1;
+            UCHAR Irq13Level:1;
+            UCHAR Irq14Level:1;
+            UCHAR Irq15Level:1;
+        } Slave;
+    };
+    USHORT Bits;
+} EISA_ELCR, *PEISA_ELCR;
+
+//
 // Mm PTE/PDE to Hal PTE/PDE
 //
 #define HalAddressToPde(x) (PHARDWARE_PTE)MiAddressToPde(x)
@@ -176,8 +331,8 @@
                            IN PVOID Handler,
                            IN KINTERRUPT_MODE Mode);
 
-/* irql.c */
-VOID NTAPI HalpInitPICs(VOID);
+/* pic.c */
+VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
 
 /* udelay.c */
 VOID NTAPI HalpInitializeClock(VOID);




More information about the Ros-diffs mailing list