00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 buserror.c 00008 00009 Abstract: 00010 00011 This module implements the code necessary to process data and instruction 00012 bus errors and to set the address of the cache error routine. 00013 00014 Author: 00015 00016 David N. Cutler (davec) 31-Oct-1991 00017 00018 Environment: 00019 00020 Kernel mode only. 00021 00022 Revision History: 00023 00024 --*/ 00025 00026 #include "ki.h" 00027 00028 BOOLEAN 00029 KeBusError ( 00030 IN PEXCEPTION_RECORD ExceptionRecord, 00031 IN PKEXCEPTION_FRAME ExceptionFrame, 00032 IN PKTRAP_FRAME TrapFrame, 00033 IN PVOID VirtualAddress, 00034 IN PHYSICAL_ADDRESS PhysicalAddress 00035 ) 00036 00037 /*++ 00038 00039 Routine Description: 00040 00041 This function provides the default bus error handling routine for NT. 00042 00043 N.B. There is no return from this routine. 00044 00045 Arguments: 00046 00047 ExceptionRecord - Supplies a pointer to an exception record. 00048 00049 ExceptionFrame - Supplies a pointer to an exception frame. 00050 00051 TrapFrame - Supplies a pointer to a trap frame. 00052 00053 VirtualAddress - Supplies the virtual address of the bus error. 00054 00055 PhysicalAddress - Supplies the physical address of the bus error. 00056 00057 Return Value: 00058 00059 None. 00060 00061 --*/ 00062 00063 { 00064 00065 // 00066 // Bug check specifying the exception code, the virtual address, the 00067 // low part of the physical address, the current processor state, and 00068 // the exception PC. 00069 // 00070 00071 KeBugCheckEx(ExceptionRecord->ExceptionCode & 0xffff, 00072 (ULONG)VirtualAddress, 00073 PhysicalAddress.LowPart, 00074 TrapFrame->Psr, 00075 TrapFrame->Fir); 00076 00077 return FALSE; 00078 } 00079 00080 PHYSICAL_ADDRESS 00081 KiGetPhysicalAddress ( 00082 IN PVOID VirtualAddress 00083 ) 00084 00085 /*++ 00086 00087 Routine Description: 00088 00089 This function computes the physical address for a given virtual address. 00090 00091 Arguments: 00092 00093 VirtualAddress - Supplies the virtual address whose physical address is 00094 to be computed. 00095 00096 Return Value: 00097 00098 The physical address that correcponds to the specified virtual address. 00099 00100 --*/ 00101 00102 { 00103 PHYSICAL_ADDRESS PhysicalAddress; 00104 00105 // 00106 // If the address is a KSEG0 or KSEG1 address, then mask off the high 00107 // three address bits and return the result as the physical address. 00108 // Otherwise, call memory management to convert the virtual address to 00109 // a physical address. 00110 // 00111 00112 if (((ULONG)VirtualAddress >= KSEG0_BASE) && 00113 ((ULONG)VirtualAddress < (KSEG1_BASE + 0x20000000))) { 00114 PhysicalAddress.LowPart = (ULONG)VirtualAddress & 0x1fffffff; 00115 PhysicalAddress.HighPart = 0; 00116 return PhysicalAddress; 00117 00118 } else { 00119 return MmGetPhysicalAddress(VirtualAddress); 00120 } 00121 } 00122 00123 VOID 00124 KiDataBusError ( 00125 IN PEXCEPTION_RECORD ExceptionRecord, 00126 IN PKEXCEPTION_FRAME ExceptionFrame, 00127 IN PKTRAP_FRAME TrapFrame 00128 ) 00129 00130 /*++ 00131 00132 Routine Description: 00133 00134 This function is called to process a data bus error. The virtual and 00135 physical address of the error are computed and the data bus error 00136 processing routine is called indirectly through the PCR. NT provides 00137 a standard routine to process the error and shutdown the system. A 00138 vendor, however, can replace the standard NT routine and do additional 00139 processing if necessary via the HAL. 00140 00141 N.B. There is no return from this routine. 00142 00143 Arguments: 00144 00145 ExceptionRecord - Supplies a pointer to an exception record. 00146 00147 ExceptionFrame - Supplies a pointer to an exception frame. 00148 00149 TrapFrame - Supplies a pointer to a trap frame. 00150 00151 Return Value: 00152 00153 None. 00154 00155 --*/ 00156 00157 { 00158 00159 PVOID VirtualAddress; 00160 PHYSICAL_ADDRESS PhysicalAddress; 00161 MIPS_INSTRUCTION FaultInstruction; 00162 00163 // 00164 // Any exception that occurs during the attempted calculation of the 00165 // virtual address causes the virtual address calculation to be 00166 // aborted and the virtual address of the instruction itself is used 00167 // instead. 00168 // 00169 00170 try { 00171 00172 // 00173 // Compute the effective address of the reference. 00174 // 00175 00176 FaultInstruction.Long = *((PULONG)ExceptionRecord->ExceptionAddress); 00177 VirtualAddress = (PVOID)(KiGetRegisterValue(FaultInstruction.i_format.Rs, 00178 ExceptionFrame, 00179 TrapFrame) + 00180 FaultInstruction.i_format.Simmediate); 00181 00182 // 00183 // If an exception occurs, then abort the calculation of the virtual 00184 // address and set the virtual address equal to the instruction address. 00185 // 00186 00187 } except (EXCEPTION_EXECUTE_HANDLER) { 00188 VirtualAddress = ExceptionRecord->ExceptionAddress; 00189 } 00190 00191 // 00192 // Compute the physical address that corresponds to the data address. 00193 // 00194 00195 PhysicalAddress = KiGetPhysicalAddress(VirtualAddress); 00196 00197 // 00198 // If a value of FALSE is returned by the data bus error handling routine, 00199 // then bug check. Otherwise, assume that the error has been handled and 00200 // return. 00201 // 00202 00203 if ((PCR->DataBusError)(ExceptionRecord, 00204 ExceptionFrame, 00205 TrapFrame, 00206 VirtualAddress, 00207 PhysicalAddress) == FALSE) { 00208 00209 KeBugCheck(DATA_BUS_ERROR); 00210 } 00211 00212 return; 00213 } 00214 00215 VOID 00216 KiInstructionBusError ( 00217 IN PEXCEPTION_RECORD ExceptionRecord, 00218 IN PKEXCEPTION_FRAME ExceptionFrame, 00219 IN PKTRAP_FRAME TrapFrame 00220 ) 00221 00222 /*++ 00223 00224 Routine Description: 00225 00226 This function is called to process an instruction bus error. The virtual 00227 and physical address of the error are computed and the instruction bus 00228 error processing routine is called indirectly through the PCR. NT provides 00229 a standard routine to process the error and shutdown the system. A vendor, 00230 however, can replace the standard NT routine and do additional processing 00231 if necessary via the HAL. 00232 00233 N.B. There is no return from this routine. 00234 00235 Arguments: 00236 00237 ExceptionRecord - Supplies a pointer to an exception record. 00238 00239 ExceptionFrame - Supplies a pointer to an exception frame. 00240 00241 TrapFrame - Supplies a pointer to a trap frame. 00242 00243 Return Value: 00244 00245 None. 00246 00247 --*/ 00248 00249 { 00250 00251 PVOID VirtualAddress; 00252 PHYSICAL_ADDRESS PhysicalAddress; 00253 00254 // 00255 // Compute the physical address that corresponds to the data address. 00256 // 00257 00258 VirtualAddress = ExceptionRecord->ExceptionAddress; 00259 PhysicalAddress = KiGetPhysicalAddress(VirtualAddress); 00260 00261 // 00262 // If a value of FALSE is returned by the instructiona bus error handling 00263 // routine, then bug check. Otherwise, assume that the error has been 00264 // handled and return. 00265 // 00266 00267 if ((PCR->InstructionBusError)(ExceptionRecord, 00268 ExceptionFrame, 00269 TrapFrame, 00270 VirtualAddress, 00271 PhysicalAddress) == FALSE) { 00272 00273 KeBugCheck(INSTRUCTION_BUS_ERROR); 00274 } 00275 00276 return; 00277 } 00278 00279 VOID 00280 KeSetCacheErrorRoutine ( 00281 IN PKCACHE_ERROR_ROUTINE Routine 00282 ) 00283 00284 /*++ 00285 00286 Routine Description: 00287 00288 This function is called to set the address of the cache error routine. 00289 The cache error routine is called whenever a cache error occurs. 00290 00291 Arguments: 00292 00293 Routine - Supplies a pointer to the cache error routine. 00294 00295 Return Value: 00296 00297 None. 00298 00299 --*/ 00300 00301 { 00302 00303 // 00304 // Set the address of the cache error routine. 00305 // 00306 00307 *((PULONG)CACHE_ERROR_VECTOR) = (ULONG)Routine | KSEG1_BASE; 00308 return; 00309 }