summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halsnip/mips/xxerror.c
blob: f55c9dd81561fdc7b36c1bcc3a7336567f3c15c2 (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
//#pragma comment(exestr, "$Header: /usr4/winnt/SOURCES/halpcims/src/hal/halsnipm/mips/RCS/xxerror.c,v 1.3 1996/05/15 08:13:24 pierre Exp $")
/*--

Copyright (c) 1991  Microsoft Corporation

Module Name:

    xxerror.c

Abstract:


    This module implements the management of errors (KeBugCheckEx, HalpBusError)

Environment:

    Kernel mode only.


--*/

#include "halp.h"
#include "string.h"

// 
// Messages for CacheError routine
//

UCHAR HalpErrCacheMsg[] = "\nCACHE ERROR\n";
UCHAR HalpParityErrMsg[] = "\nPARITY ERROR\n";
UCHAR HalpAddrErrMsg[] = "Address in error not found\n";
ULONG HalpCacheErrFirst = 0;

ULONG HalpKeBugCheck0;
ULONG HalpKeBugCheck1;
ULONG HalpKeBugCheck2;
ULONG HalpKeBugCheck3;
ULONG HalpKeBugCheck4;

VOID
HalpBugCheckCallback (
    IN PVOID Buffer,
    IN ULONG Length
    );

//
// Define bug check information buffer and callback record.
//

HALP_BUGCHECK_BUFFER HalpBugCheckBuffer;

KBUGCHECK_CALLBACK_RECORD HalpCallbackRecord;

UCHAR HalpComponentId[] = "hal.dll";

//
// Define BugCheck Number and BugCheck Additional Message
//

ULONG HalpBugCheckNumber = (ULONG)(-1);

PUCHAR HalpBugCheckMessage[] = {
"MP_Agent fatal error\n",               // #0
"ASIC PCI TRANSFER ERROR\n",            // #1
"ECC SINGLE ERROR COUNTER OVERFLOW\n",  // #2       
"UNCORRECTABLE ECC ERROR\n",            // #3
"PCI TIMEOUT ERROR\n",                  // #4
"MP_BUS PARITY ERROR\n",                // #5
"MP_BUS REGISTER SIZE ERROR\n",         // #6
"MEMORY ADDRESS ERROR\n",               // #7
"MEMORY SLOT ERROR\n",                  // #8
"MEMORY CONFIG ERROR\n",                // #9
"PCI INITIATOR INTERRUPT ERROR\n",      // #10
"PCI TARGET INTERRUPT ERROR\n",         // #11
"PCI PARITY INTERRUPT ERROR\n",         // #12
"MULTIPLE PCI INITIATOR ERROR\n",       // #13
"MULTIPLE PCI TARGET ERROR\n",          // #14       
"MULTIPLE PCI PARITY ERROR\n",          // #15
"DATA_BUS_ERROR\n",                     // #16                  
"INSTRUCTION_BUS_ERROR\n",              // #17
"PARITY ERROR\n",                       // #18
"CACHE ERROR\n"                         // #19
};

VOID
HalpBugCheckCallback (
    IN PVOID Buffer,
    IN ULONG Length
    )

/*++

Routine Description:

    This function is called when a bug check occurs. Its function is
    to dump the state of the memory error registers into a bug check
    buffer.

Arguments:

    Buffer - Supplies a pointer to the bug check buffer.

    Length - Supplies the length of the bug check buffer in bytes.

Return Value:

    None.

--*/

{

    PHALP_BUGCHECK_BUFFER DumpBuffer;
    PUCHAR p,q;

    if (HalpBugCheckNumber == -1) return; // that is not a HAL bugcheck ...

    //
    // Capture the failed memory address and diagnostic registers.
    //

    DumpBuffer = (PHALP_BUGCHECK_BUFFER)Buffer;

    DumpBuffer->Par0 = HalpKeBugCheck0;
    DumpBuffer->Par1 = HalpKeBugCheck1;
    DumpBuffer->Par2 = HalpKeBugCheck2;
    DumpBuffer->Par3 = HalpKeBugCheck3;
    DumpBuffer->Par4 = HalpKeBugCheck4;
    DumpBuffer->MainBoard = HalpMainBoard;
    p = DumpBuffer->TEXT;q = HalpBugCheckMessage[HalpBugCheckNumber];
    while (*q) *p++ = *q++;
    return;
}


BOOLEAN
HalpBusError (
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PKTRAP_FRAME TrapFrame,
    IN PVOID VirtualAddress,
    IN PHYSICAL_ADDRESS PhysicalAddress
    )

/*++

Routine Description:

    This function provides the default bus error handling routine for NT.

    N.B. There is no return from this routine.

Arguments:

    ExceptionRecord - Supplies a pointer to an exception record.

    ExceptionFrame - Supplies a pointer to an exception frame.

    TrapFrame - Supplies a pointer to a trap frame.

    VirtualAddress - Supplies the virtual address of the bus error.

    PhysicalAddress - Supplies the physical address of the bus error.

Return Value:

    None.

--*/

{
    
    KIRQL OldIrql;
    UCHAR IntSource;
    UCHAR MaStatus;
    ULONG Itpend;


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

     

    if (HalpIsTowerPci){
        // stop the extra-timer
    
        WRITE_REGISTER_UCHAR(PCI_TOWER_TIMER_CMD_REG,0);


        HalpPciTowerInt3Dispatch(&HalpInt3Interrupt,(PVOID)PCI_TOWER_INTERRUPT_SOURCE_REGISTER);
    }else{
        
        IntSource = READ_REGISTER_UCHAR(PCI_INTERRUPT_SOURCE_REGISTER);

        IntSource ^= PCI_INTERRUPT_MASK;        // XOR the low active bits with 1 gives 1
                                            // and XOR the high active with 0 gives 1
        if ( IntSource & PCI_INT2_MASK) {
    
            MaStatus   = READ_REGISTER_UCHAR(PCI_MSR_ADDR);
            if (HalpMainBoard == DesktopPCI) {
                MaStatus  ^= PCI_MSR_MASK_D;
            } else {
                MaStatus  ^= PCI_MSR_MASK_MT;
            }//(HalpMainBoard == DesktopPCI) 

            //
            // look for an ASIC interrupt
            //

            if ( MaStatus & PCI_MSR_ASIC_MASK){

                Itpend = READ_REGISTER_ULONG(PCI_ITPEND_REGISTER);

                if ( Itpend & (PCI_ASIC_ECCERROR | PCI_ASIC_TRPERROR)) {

                    ULONG AsicErrAddr, ErrAddr, Syndrome, ErrStatus;

                    ErrAddr = READ_REGISTER_ULONG(PCI_ERRADDR_REGISTER);
                    Syndrome = READ_REGISTER_ULONG(PCI_SYNDROME_REGISTER);
                    ErrStatus = READ_REGISTER_ULONG(PCI_ERRSTATUS_REGISTER);

                    if (ErrStatus & PCI_MEMSTAT_PARERR) {
                        // Parity error (PCI_ASIC <-> CPU)  
#if DBG
                        DebugPrint(("pci_memory_error : errstatus=0x%x Add error=0x%x syndrome=0x%x \n",
                        ErrStatus,ErrAddr,Syndrome));
                        DbgBreakPoint();
#else
                        HalpDisableInterrupts();  // for the MATROX boards...
                        HalpColumn = 0;HalpRow = 0;    // if we already were in VGA mode
                        HalDisplayString("\n");
                        HalpClearVGADisplay();
                        HalpBugCheckNumber = 1;
                        HalDisplayString(HalpBugCheckMessage[HalpBugCheckNumber]); // "PARITY ERROR\n"
                        HalpKeBugCheckEx(NMI_HARDWARE_FAILURE,HalpBugCheckNumber,ErrAddr,HalpComputeNum((UCHAR *)ErrAddr),Syndrome);
#endif
                    }//if (ErrStatus & PCI_MEMSTAT_PARERR)

             
                 
                    if (ErrStatus & PCI_MEMSTAT_ECCERR) {

                        AsicErrAddr &= 0xfffffff8;
                        ErrAddr = HalpFindEccAddr(AsicErrAddr,(PVOID)PCI_ERRSTATUS_REGISTER,(PVOID)PCI_MEMSTAT_ECCERR);
                        if (ErrAddr == -1) ErrAddr = AsicErrAddr;

#if DBG
                        // UNIX => PANIC
                        DebugPrint(("pci_ecc_error : errstatus=0x%x Add error=0x%x syndrome=0x%x \n",
                            ErrStatus,ErrAddr,Syndrome));
                        DbgBreakPoint();
#else
                        HalpDisableInterrupts();  // for the MATROX boards...
                        HalpColumn = 0;HalpRow = 0;    // if we already were in VGA mode
                        HalDisplayString("\n");
                        HalpClearVGADisplay();
                        HalpBugCheckNumber = 3;
                        HalDisplayString(HalpBugCheckMessage[HalpBugCheckNumber]); // "UNCORRECTABLE ECC ERROR\n"
                        HalpKeBugCheckEx(NMI_HARDWARE_FAILURE,HalpBugCheckNumber,ErrAddr,HalpComputeNum((UCHAR *)ErrAddr),Syndrome);
#endif
                    } //if (ErrStatus & PCI_MEMSTAT_ECCERR)
                } //if ( Itpend & (PCI_ASIC_ECCERROR | PCI_ASIC_TRPERROR))
                
                
            }//if ( MaStatus & PCI_MSR_ASIC_MASK)

        }//if ( IntSource & PCI_INT2_MASK)
    }//if (HalpIsTowerPci)

    // arrive here if no interruption found
    HalpDisableInterrupts();  // for the MATROX boards...
    HalpColumn = 0;HalpRow = 0;    // if we already were in VGA mode
    HalDisplayString("\n");
    HalpClearVGADisplay();
    if  (( ExceptionRecord->ExceptionCode & DATA_BUS_ERROR ) == DATA_BUS_ERROR) {
        HalpBugCheckNumber = 16;
        HalDisplayString(HalpBugCheckMessage[HalpBugCheckNumber]); // "DATA_BUS_ERROR\n"                  
    } else {
        HalpBugCheckNumber = 17;
        HalDisplayString(HalpBugCheckMessage[HalpBugCheckNumber]); // "INSTRUCTION_BUS_ERROR\n"                  
    }

    HalpKeBugCheckEx(ExceptionRecord->ExceptionCode ,
                 HalpBugCheckNumber,
                 (ULONG)VirtualAddress,
                 (ULONG)PhysicalAddress.LowPart,
                  0);
    
    KiReleaseSpinLock(&HalpInterruptLock);
    KeLowerIrql(OldIrql);

return FALSE;
}