Implemented missing KeRaiseIrqlToXxLevel() functions
[reactos.git] / reactos / ntoskrnl / hal / x86 / irql.c
index d505248..fcfe713 100644 (file)
 
 /* GLOBALS ******************************************************************/
 
+/* FIXME: this should be in a header file */
+#define NR_IRQS         (16)
+#define IRQ_BASE        (0x40)
+
 /*
  * PURPOSE: Current irq level
  */
@@ -26,8 +30,30 @@ static KIRQL CurrentIrql = HIGH_LEVEL;
 
 extern ULONG DpcQueueSize;
 
+static VOID KeSetCurrentIrql(KIRQL newlvl);
+
 /* FUNCTIONS ****************************************************************/
 
+VOID HalpInitPICs(VOID)
+{
+   /* Initialization sequence */
+   WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11);
+   WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11);
+   /* Start of hardware irqs (0x20) */
+   WRITE_PORT_UCHAR((PUCHAR)0x21, 0x40);
+   WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x48);
+   /* 8259-1 is master */
+   WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4);
+   /* 8259-2 is slave */
+   WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2);
+   /* 8086 mode */
+   WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
+   WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);   
+   /* Mask off all interrupts from PICs */
+   WRITE_PORT_UCHAR((PUCHAR)0x21, 0xff);
+   WRITE_PORT_UCHAR((PUCHAR)0xa1, 0xff);
+}
+
 #if 0
 static unsigned int HiGetCurrentPICMask(void)
 {
@@ -68,9 +94,9 @@ static VOID HiSwitchIrql(KIRQL oldIrql)
      {
        unsigned int current_mask = 0;
        
-       for (i=(CurrentIrql-DISPATCH_LEVEL);i>DISPATCH_LEVEL;i--)
+       for (i=CurrentIrql; i>DISPATCH_LEVEL; i--)
          {
-            set_bit(NR_DEVICE_SPECIFIC_LEVELS - i,&current_mask);
+            current_mask = current_mask | (1 << (HIGH_LEVEL - i));
          }
        
        HiSetCurrentPICMask(current_mask);
@@ -92,7 +118,7 @@ static VOID HiSwitchIrql(KIRQL oldIrql)
          {
             KeSetCurrentIrql(DISPATCH_LEVEL);
             __asm__("sti\n\t");
-            KeDrainDpcQueue();
+            KiDispatchInterrupt();
             __asm__("cli\n\t");
             KeSetCurrentIrql(PASSIVE_LEVEL);
          }
@@ -106,7 +132,7 @@ static VOID HiSwitchIrql(KIRQL oldIrql)
      {
        KeSetCurrentIrql(APC_LEVEL);
        __asm__("sti\n\t");
-       KeCallApcsThread();
+       KiDeliverApc(0, 0, 0);
        __asm__("cli\n\t");
        KeSetCurrentIrql(PASSIVE_LEVEL);
        __asm__("sti\n\t");
@@ -118,23 +144,23 @@ static VOID HiSwitchIrql(KIRQL oldIrql)
 }
 
 
-VOID KeSetCurrentIrql(KIRQL newlvl)
+KIRQL STDCALL KeGetCurrentIrql (VOID)
 /*
- * PURPOSE: Sets the current irq level without taking any action
+ * PURPOSE: Returns the current irq level
+ * RETURNS: The current irq level
  */
 {
-//   DPRINT("KeSetCurrentIrql(newlvl %x)\n",newlvl);
-   CurrentIrql = newlvl;
+   return(CurrentIrql);
 }
 
 
-KIRQL STDCALL KeGetCurrentIrql (VOID)
+static VOID KeSetCurrentIrql(KIRQL newlvl)
 /*
- * PURPOSE: Returns the current irq level
- * RETURNS: The current irq level
+ * PURPOSE: Sets the current irq level without taking any action
  */
 {
-   return(CurrentIrql);
+//   DPRINT("KeSetCurrentIrql(newlvl %x)\n",newlvl);
+   CurrentIrql = newlvl;
 }
 
 
@@ -282,4 +308,132 @@ KeRaiseIrql (
        *OldIrql = KfRaiseIrql (NewIrql);
 }
 
+
+/**********************************************************************
+ * NAME                                                        EXPORTED
+ *     KeRaiseIrqlToDpcLevel
+ *
+ * DESCRIPTION
+ *     Raises the hardware priority (irql) to DISPATCH level
+ *
+ * ARGUMENTS
+ *     None
+ *
+ * RETURN VALUE
+ *     Previous irq level
+ *
+ * NOTES
+ *     Calls KfRaiseIrql
+ */
+
+KIRQL
+STDCALL
+KeRaiseIrqlToDpcLevel (VOID)
+{
+       return KfRaiseIrql (DISPATCH_LEVEL);
+}
+
+
+/**********************************************************************
+ * NAME                                                        EXPORTED
+ *     KeRaiseIrqlToSynchLevel
+ *
+ * DESCRIPTION
+ *     Raises the hardware priority (irql) to CLOCK2 level
+ *
+ * ARGUMENTS
+ *     None
+ *
+ * RETURN VALUE
+ *     Previous irq level
+ *
+ * NOTES
+ *     Calls KfRaiseIrql
+ */
+
+KIRQL
+STDCALL
+KeRaiseIrqlToSynchLevel (VOID)
+{
+//     return KfRaiseIrql (CLOCK2_LEVEL);
+       UNIMPLEMENTED;
+}
+
+
+BOOLEAN STDCALL HalBeginSystemInterrupt (ULONG Vector,
+                                        KIRQL Irql,
+                                        PKIRQL OldIrql)
+{
+   if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS)
+       return FALSE;
+
+   /* Send EOI to the PICs */
+   outb(0x20,0x20);
+   if ((Vector-IRQ_BASE)>=8)
+     {
+       outb(0xa0,0x20);
+     }
+
+   *OldIrql = KeGetCurrentIrql();
+   if (Vector-IRQ_BASE != 0)
+     {
+       DPRINT("old_level %d\n",*OldIrql);
+     }
+   KeSetCurrentIrql(Irql);
+
+   return TRUE;
+}
+
+
+VOID STDCALL HalEndSystemInterrupt (KIRQL Irql,
+                                   ULONG Unknown2)
+{
+   KeSetCurrentIrql(Irql);
+}
+
+
+BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector,
+                                          ULONG Unknown2)
+{
+   ULONG irq;
+
+   if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS)
+       return FALSE;
+
+   irq = Vector - IRQ_BASE;
+   if (irq<8)
+     {
+       outb(0x21,inb(0x21)|(1<<irq));
+     }
+   else
+     {
+       outb(0xa1,inb(0xa1)|(1<<(irq-8)));
+     }
+
+   return TRUE;
+}
+
+
+BOOLEAN STDCALL HalEnableSystemInterrupt (ULONG Vector,
+                                         ULONG Unknown2,
+                                         ULONG Unknown3)
+{
+   ULONG irq;
+
+   if (Vector < IRQ_BASE || Vector > IRQ_BASE + NR_IRQS)
+       return FALSE;
+
+   irq = Vector - IRQ_BASE;
+   if (irq<8)
+     {
+       outb(0x21,inb(0x21)&(~(1<<irq)));
+     }
+   else
+     {
+       outb(0xa1,inb(0xa1)&(~(1<<(irq-8))));
+     }
+
+   return TRUE;
+}
+
 /* EOF */