xref: /reactos/hal/halx86/legacy/bus/sysbus.c (revision 8a978a17)
1 /*
2  * PROJECT:         ReactOS HAL
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            hal/halx86/legacy/bus/sysbus.c
5  * PURPOSE:
6  * PROGRAMMERS:     Stefan Ginsberg (stefan.ginsberg@reactos.org)
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <hal.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* GLOBALS ********************************************************************/
16 
17 /* PRIVATE FUNCTIONS **********************************************************/
18 
19 BOOLEAN
20 NTAPI
21 HalpTranslateSystemBusAddress(IN PBUS_HANDLER BusHandler,
22                               IN PBUS_HANDLER RootHandler,
23                               IN PHYSICAL_ADDRESS BusAddress,
24                               IN OUT PULONG AddressSpace,
25                               OUT PPHYSICAL_ADDRESS TranslatedAddress)
26 {
27     PSUPPORTED_RANGE Range = NULL;
28 
29     /* Check what kind of address space this is */
30     switch (*AddressSpace)
31     {
32         /* Memory address */
33         case 0:
34 
35             /* Loop all prefetch memory */
36             for (Range = &BusHandler->BusAddresses->PrefetchMemory;
37                  Range;
38                  Range = Range->Next)
39             {
40                 /* Check if it's in a valid range */
41                 if ((BusAddress.QuadPart >= Range->Base) &&
42                     (BusAddress.QuadPart <= Range->Limit))
43                 {
44                     /* Get out */
45                     break;
46                 }
47             }
48 
49             /* Check if we haven't found anything yet */
50             if (!Range)
51             {
52                 /* Loop all bus memory */
53                 for (Range = &BusHandler->BusAddresses->Memory;
54                      Range;
55                      Range = Range->Next)
56                 {
57                     /* Check if it's in a valid range */
58                     if ((BusAddress.QuadPart >= Range->Base) &&
59                         (BusAddress.QuadPart <= Range->Limit))
60                     {
61                         /* Get out */
62                         break;
63                     }
64                 }
65             }
66 
67             /* Done */
68             break;
69 
70         /* I/O Space */
71         case 1:
72 
73             /* Loop all bus I/O memory */
74             for (Range = &BusHandler->BusAddresses->IO;
75                  Range;
76                  Range = Range->Next)
77             {
78                 /* Check if it's in a valid range */
79                 if ((BusAddress.QuadPart >= Range->Base) &&
80                     (BusAddress.QuadPart <= Range->Limit))
81                 {
82                     /* Get out */
83                     break;
84                 }
85             }
86 
87             /* Done */
88             break;
89     }
90 
91     /* Check if we found a range */
92     if (Range)
93     {
94         /* Do the translation and return the kind of address space this is */
95         TranslatedAddress->QuadPart = BusAddress.QuadPart + Range->SystemBase;
96         if ((TranslatedAddress->QuadPart != BusAddress.QuadPart) ||
97             (*AddressSpace != Range->SystemAddressSpace))
98         {
99             /* Different than what the old HAL would do */
100             DPRINT1("Translation of %I64x is %I64x %s\n",
101                     BusAddress.QuadPart, TranslatedAddress->QuadPart,
102                     Range->SystemAddressSpace ? "In I/O Space" : "In RAM");
103         }
104         *AddressSpace = Range->SystemAddressSpace;
105         return TRUE;
106     }
107 
108     /* Nothing found */
109     DPRINT1("Translation of %I64x failed!\n", BusAddress.QuadPart);
110     return FALSE;
111 }
112 
113 ULONG
114 NTAPI
115 HalpGetRootInterruptVector(IN ULONG BusInterruptLevel,
116                            IN ULONG BusInterruptVector,
117                            OUT PKIRQL Irql,
118                            OUT PKAFFINITY Affinity)
119 {
120     UCHAR SystemVector;
121 
122     /* Validate the IRQ */
123     if (BusInterruptLevel > 23)
124     {
125         /* Invalid vector */
126         DPRINT1("IRQ %lx is too high!\n", BusInterruptLevel);
127         return 0;
128     }
129 
130     /* Get the system vector */
131     SystemVector = HalpIrqToVector((UCHAR)BusInterruptLevel);
132 
133     /* Return the IRQL and affinity */
134     *Irql = HalpVectorToIrql(SystemVector);
135     *Affinity = HalpDefaultInterruptAffinity;
136     ASSERT(HalpDefaultInterruptAffinity);
137 
138     /* Return the vector */
139     return SystemVector;
140 }
141 
142 ULONG
143 NTAPI
144 HalpGetSystemInterruptVector(IN PBUS_HANDLER BusHandler,
145                              IN PBUS_HANDLER RootHandler,
146                              IN ULONG BusInterruptLevel,
147                              IN ULONG BusInterruptVector,
148                              OUT PKIRQL Irql,
149                              OUT PKAFFINITY Affinity)
150 {
151     ULONG Vector;
152 
153     /* Get the root vector */
154     Vector = HalpGetRootInterruptVector(BusInterruptLevel,
155                                         BusInterruptVector,
156                                         Irql,
157                                         Affinity);
158 
159     /* Check if the vector is owned by the HAL and fail if it is */
160     if (HalpIDTUsageFlags[Vector].Flags & IDT_REGISTERED) DPRINT1("Vector %lx is ALREADY IN USE!\n", Vector);
161     return (HalpIDTUsageFlags[Vector].Flags & IDT_REGISTERED) ? 0 : Vector;
162 }
163 
164 /* EOF */
165