fixes and changes to support IDE driver
[reactos.git] / reactos / ntoskrnl / hal / x86 / irql.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: mkernel/hal/irql.c
5 * PURPOSE: Implements IRQLs
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <windows.h>
12 #include <ddk/ntddk.h>
13 #include <internal/bitops.h>
14 #include <internal/hal/io.h>
15
16 #define NDEBUG
17 #include <internal/debug.h>
18
19 /* GLOBALS ******************************************************************/
20
21 /*
22 * PURPOSE: Current irq level
23 */
24 static KIRQL CurrentIrql = HIGH_LEVEL;
25
26 /* FUNCTIONS ****************************************************************/
27
28 static unsigned int pic_get_current_mask(void)
29 {
30 unsigned int mask;
31
32 mask = inb_p(0x21);
33 mask = mask | (inb_p(0xa1)<<8);
34 }
35
36 static unsigned int pic_set_current_mask(unsigned int mask)
37 {
38 outb_p(0x21,mask & 0xff);
39 outb_p(0xa1,(mask >> 8) & 0xff);
40 }
41
42 static void switch_irql(void)
43 /*
44 * FUNCTION: Switches to the current irql
45 * NOTE: Must be called with interrupt disabled
46 */
47 {
48 unsigned int i;
49
50 if (CurrentIrql == HIGH_LEVEL)
51 {
52 pic_set_current_mask(0xffff);
53 return;
54 }
55 if (CurrentIrql > DISPATCH_LEVEL)
56 {
57 unsigned int current_mask = 0;
58
59 for (i=(CurrentIrql-DISPATCH_LEVEL);i>DISPATCH_LEVEL;i--)
60 {
61 set_bit(NR_DEVICE_SPECIFIC_LEVELS - i,&current_mask);
62 }
63
64 pic_set_current_mask(current_mask);
65 __asm__("sti\n\t");
66 return;
67 }
68
69 if (CurrentIrql <= DISPATCH_LEVEL)
70 {
71 pic_set_current_mask(0);
72 __asm__("sti\n\t");
73 return;
74 }
75 }
76
77 VOID KeSetCurrentIrql(KIRQL newlvl)
78 /*
79 * PURPOSE: Sets the current irq level without taking any action
80 */
81 {
82 DPRINT("KeSetCurrentIrql(newlvl %x)\n",newlvl);
83 CurrentIrql = newlvl;
84 }
85
86 KIRQL KeGetCurrentIrql()
87 /*
88 * PURPOSE: Returns the current irq level
89 * RETURNS: The current irq level
90 */
91 {
92 return(CurrentIrql);
93 }
94
95 VOID KeLowerIrql(KIRQL NewIrql)
96 /*
97 * PURPOSE: Restores the irq level on the current processor
98 * ARGUMENTS:
99 * NewIrql = Irql to lower to
100 */
101 {
102 __asm__("cli\n\t");
103
104 DPRINT("NewIrql %x CurrentIrql %x\n",NewIrql,CurrentIrql);
105 assert(NewIrql <= CurrentIrql);
106 CurrentIrql = NewIrql;
107 switch_irql();
108 }
109
110 VOID KeRaiseIrql(KIRQL NewIrql, PKIRQL OldIrql)
111 /*
112 * FUNCTION: Raises the hardware priority (irql)
113 * ARGUMENTS:
114 * NewIrql = Irql to raise to
115 * OldIrql (OUT) = Caller supplied storage for the previous irql
116 */
117 {
118 /*
119 * sanity check
120 */
121 DPRINT("CurrentIrql %x NewIrql %x OldIrql %x\n",CurrentIrql,NewIrql,
122 OldIrql);
123 if (NewIrql < CurrentIrql)
124 {
125 DbgPrint("%s:%d CurrentIrql %x NewIrql %x OldIrql %x\n",__FILE__,__LINE__,
126 CurrentIrql,NewIrql,OldIrql);
127 for(;;);
128 }
129
130 __asm__("cli\n\t");
131 *OldIrql = CurrentIrql;
132 CurrentIrql = NewIrql;
133 // *OldIrql = InterlockedExchange(&CurrentIrql,NewIrql);
134 DPRINT("NewIrql %x OldIrql %x CurrentIrql %x\n",NewIrql,*OldIrql,
135 CurrentIrql);
136 switch_irql();
137 }
138
139
140