summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halsni4x/mips/jxsysint.c
blob: ee70178da0911fbc2e9b1d1b45422ed3adf5b659 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
#pragma comment(exestr, "$Header: /usr4/winnt/SOURCES/ddk351/src/hal/halsni4x/mips/RCS/jxsysint.c,v 1.1 1995/05/19 11:20:52 flo Exp $")
/*++

Copyright (c) 1993-94 Siemens Nixdorf Informationssysteme AG
Copyright (c) 1991  Microsoft Corporation

Module Name:

    jxsysint.c

Abstract:

    This module implements the HAL enable/disable system interrupt, and
    request interprocessor interrupt routines for a MIPS R3000 or R4000
    SNI system.

Environment:

    Kernel mode

--*/

#include "halp.h"


VOID
HalDisableSystemInterrupt (
    IN ULONG Vector,
    IN KIRQL Irql
    )

/*++

Routine Description:

    This routine disables the specified system interrupt.

Arguments:

    Vector - Supplies the vector of the system interrupt that is disabled.

    Irql - Supplies the IRQL of the interrupting source.

Return Value:

    None.

--*/

{

    KIRQL OldIrql;


    //
    // Raise IRQL to the highest level.
    //

    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    KiAcquireSpinLock(&HalpSystemInterruptLock);


    //
    // If the vector number is within the range of the onboard interrupts, then
    // disable the onboard interrrupt.
    // This may be an Isa (Desktop) or Isa/Eisa (Minitower) Interrupt
    //

    if (Vector >= ONBOARD_VECTORS &&
        Vector <= MAXIMUM_ONBOARD_VECTOR &&
        Irql == EISA_DEVICE_LEVEL) {
            HalpDisableOnboardInterrupt(Vector);
    }


    //
    // If the vector number is within the range of the EISA interrupts, then
    // disable the EISA interrrupt on the Eisa Backplane (Eisa Extension).
    //

    else if (Vector >= EISA_VECTORS &&
             Vector <= MAXIMUM_EISA_VECTOR &&
             Irql == EISA_DEVICE_LEVEL) {

        HalpDisableEisaInterrupt(Vector);
    }

    //
    // Lower IRQL to the previous level.
    //

    KiReleaseSpinLock(&HalpSystemInterruptLock);
    KeLowerIrql(OldIrql);

    return;
}

BOOLEAN
HalEnableSystemInterrupt (
    IN ULONG Vector,
    IN KIRQL Irql,
    IN KINTERRUPT_MODE InterruptMode
    )

/*++

Routine Description:

    This routine enables the specified system interrupt.

Arguments:

    Vector - Supplies the vector of the system interrupt that is enabled.

    Irql - Supplies the IRQL of the interrupting source.

    InterruptMode - Supplies the mode of the interrupt; LevelSensitive or
        Latched.

Return Value:

    TRUE if the system interrupt was enabled

--*/

{

    KIRQL OldIrql;

    //
    // Raise IRQL to the highest level.
    //

    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    KiAcquireSpinLock(&HalpSystemInterruptLock);

    //
    // If the vector number is within the range of the onboard interrupts, then
    // enable the onboard interrrupt and set the Level/Edge register to latched,
    // because the onboard Opti 499 (Desktop)is a real Isa Controler and cannot share interrupts.
    // even the i82350 Chipset on the Minitower cannot share interrupts (why ?)
    //

    if (Vector >= ONBOARD_VECTORS &&
        Vector <= MAXIMUM_ONBOARD_VECTOR &&
        Irql == EISA_DEVICE_LEVEL) {

        if (HalpIsRM200)
            //
            // the RM200 has an Opti 499 Chip, which is an "real" Isa Chipset
            // so we cannot support Level sensitive Interrupts ...
            //

            HalpEnableOnboardInterrupt( Vector, Latched);
        else
            HalpEnableOnboardInterrupt( Vector, InterruptMode);
    }

    //
    // If the vector number is within the range of the EISA interrupts, then
    // enable the EISA interrrupt in the Eisa Backplane (Eisa Extension) and set the Level/Edge register.
    //

    else if (Vector >= EISA_VECTORS &&
             Vector <=  MAXIMUM_EISA_VECTOR &&
             Irql == EISA_DEVICE_LEVEL) {
        HalpEnableEisaInterrupt( Vector, InterruptMode);
    }

    //
    // Lower IRQL to the previous level.
    //

    KiReleaseSpinLock(&HalpSystemInterruptLock);
    KeLowerIrql(OldIrql);


    return TRUE;
}

ULONG
HalGetInterruptVector(
    IN INTERFACE_TYPE  InterfaceType,
    IN ULONG BusNumber,
    IN ULONG BusInterruptLevel,
    IN ULONG BusInterruptVector,
    OUT PKIRQL Irql,
    OUT PKAFFINITY Affinity
    )

/*++

Routine Description:

    This function returns the system interrupt vector and IRQL level
    corresponding to the specified bus interrupt level and/or vector. The
    system interrupt vector and IRQL are suitable for use in a subsequent call
    to KeInitializeInterrupt.

Arguments:

    InterfaceType - Supplies the type of bus which the vector is for.

    BusNumber - Supplies the bus number for the device.

    BusInterruptLevel - Supplies the bus specific interrupt level.

    BusInterruptVector - Supplies the bus specific interrupt vector.

    Irql - Returns the system request priority.

    Affinity - Returns the affinity for the requested vector

Return Value:

    Returns the system interrupt vector corresponding to the specified device.

--*/

{


    *Affinity = 1;

    //
    // If this is for the internal bus then just return the passed parameter.
    //

    if (InterfaceType == Internal) {

        if (BusInterruptVector >= ONBOARD_VECTORS &&
            BusInterruptVector <= MAXIMUM_ONBOARD_VECTOR ) {

            // 
            // this is one of the onboard components of the PC core
            // (floppy, serial, parallel, mouse etc.)
            // they should be configured in the Firmware tree with an Offset of 
            // ONBOARD_VECTORS (e.g. 0x10 to make them different to the real onboard components
            // like scsi or ethernet) and with an Irql of EISA_DEVICE_LEVEL (actually 4)
            // we need Firmware release 1.04 or later ...
            //

            //
            // Bus interrupt vector 2 of Onboard PC core interrupts is actually mapped to 
            // vector 9 in the Isa/Eisa hardware.
            //

            if (BusInterruptVector == ONBOARD_VECTORS + 2) {
                BusInterruptVector = ONBOARD_VECTORS + 9;
            }

            //
            // The IRQL level is always equal to the EISA level.
            //

            *Irql = EISA_DEVICE_LEVEL;

            return(BusInterruptVector);
        }

        //
        // these are the "real" Onboard components (scsi and Ethernet)
        // Return the passed parameters.
        //

        *Irql = (KIRQL) BusInterruptLevel;

        //
        // this is the special case of the onboard Ethernet Controller
        // At CPU Modules with an R4400 PC this goes directly to corresponding
        // Cause Register Bit IP7 (bad bad ..)
        // on MUltiPro machines this IP7 is used for IPI Interrupts so we have to
        // manipulate this.
        //

	if (BusInterruptVector == NET_DEFAULT_VECTOR){

            extern BOOLEAN HalpProcPc;
            //
            // the RM200 and all SC machines have a central Device Interrupt
            // which is software managed by this HAL ...
            // leave al other cases as they are ...
            //

            if ( ((HalpProcPc == FALSE) && (HalpProcessorId != ORIONSC)) || (HalpMainBoard==M8036)) {

		if (HalpProcessorId == MPAGENT) {

                	BusInterruptVector = NET_LEVEL;
                	*Irql = (KIRQL) NETMULTI_LEVEL;
        		*Affinity = 1 << HalpNetProcessor;  // proc 1 if started

		} else {
		
                	BusInterruptVector = NET_LEVEL;

                	//
                	// Irql is equal to the most common Device Interrupt Level
                	// (currently 4)
                	//

                	*Irql = (KIRQL) SCSIEISA_LEVEL;
		}

            }

		  	return ( BusInterruptVector);
        }

        //
        // this is another special case of the EIP Interrupt for RM400 Tower
        // we have an agreement with the EIP developer 
        // we meet each other on InterruptVector 15, so we limit the Irql to Device Level
	//

	if ( (HalpMainBoard==M8032) && (BusInterruptVector == EIP_VECTOR) ){

            //
            // Irql is equal to the most common Device Interrupt Level
            // (currently 4)
            //

            if (HalpProcessorId == MPAGENT) *Irql = (KIRQL) INT3_LEVEL; else *Irql = (KIRQL) SCSIEISA_LEVEL;

        }

        return(BusInterruptVector);
    }

    if (InterfaceType != Isa && InterfaceType != Eisa) {

        //
        // Not on this system return nothing.
        //

        *Affinity = 0;
        *Irql = 0;
        return(0);
    }

    //
    // Isa/Eisa Interrupts which are not configured in the Firmware
    // (boards should be located in the Expansion Slots ...)
    // The IRQL level is always equal to the EISA level.
    // WARNING: some driver call HalGetInterruptVector 
    //          with the BusInterruptLevel == BusInterruptVector
    //          but some call it with different values.
    //          In this part of the source tree we match the Jazz reference 
    //          sources (see Internal handling; which is different)
    //

    *Irql = EISA_DEVICE_LEVEL;

    //
    // Bus interrupt 2 is actually mapped to bus interrupt 9 in the Isa/Eisa
    // hardware.
    //

    if (BusInterruptLevel == 2) {
        BusInterruptLevel = 9;
    }

    //
    // The vector is equal to the specified bus level plus the ONBOARD/EISA_VECTORS.
    // in any case the interrupt vector for Isa or Eisa card has to be on the
    // Backplane, so if an Eisa Extension is installed this is an Eisa Interrupt
    //  

    if (HalpEisaExtensionInstalled ) {
        return( BusInterruptLevel + EISA_VECTORS);
    } else

    // 
    // if there is no Eisa Extension installed
    // all Isa/Eisa Interrupts should be handled by the onboard PC core
    //

    return(BusInterruptLevel + ONBOARD_VECTORS);

}