Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

kdcpuapi.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 00005 Module Name: 00006 00007 kdcpuapi.c 00008 00009 Abstract: 00010 00011 This module implements CPU specific remote debug APIs. 00012 00013 Author: 00014 00015 Chuck Bauman 14-Aug-1993 00016 00017 Revision History: 00018 00019 Based on Mark Lucovsky (markl) MIPS version 04-Sep-1990 00020 00021 --*/ 00022 00023 #include "kdp.h" 00024 #define END_OF_CONTROL_SPACE (sizeof(KPROCESSOR_STATE)) 00025 00026 00027 VOID 00028 KdpSetLoadState ( 00029 IN PDBGKD_WAIT_STATE_CHANGE WaitStateChange, 00030 IN PCONTEXT ContextRecord 00031 ) 00032 00033 /*++ 00034 00035 Routine Description: 00036 00037 Fill in the Wait_State_Change message record for the load symbol case. 00038 00039 Arguments: 00040 00041 WaitStateChange - Supplies pointer to record to fill in 00042 00043 ContextRecord - Supplies a pointer to a context record. 00044 00045 Return Value: 00046 00047 None. 00048 00049 --*/ 00050 00051 { 00052 00053 ULONG Count; 00054 PVOID End; 00055 00056 // 00057 // Copy the immediate instruction stream into the control report structure. 00058 // 00059 00060 Count = KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00061 WaitStateChange->ProgramCounter, 00062 DBGKD_MAXSTREAM); 00063 00064 WaitStateChange->ControlReport.InstructionCount = (USHORT)Count; 00065 00066 // 00067 // Clear breakpoints in the copied instruction stream. If any breakpoints 00068 // are cleared, then recopy the instruction stream. 00069 // 00070 00071 End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1); 00072 if (KdpDeleteBreakpointRange(WaitStateChange->ProgramCounter, End) != FALSE) { 00073 KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00074 WaitStateChange->ProgramCounter, 00075 WaitStateChange->ControlReport.InstructionCount); 00076 } 00077 00078 // 00079 // Copy the context record into the wait state change structure. 00080 // 00081 00082 KdpMoveMemory((PCHAR)&WaitStateChange->Context, 00083 (PCHAR)ContextRecord, 00084 sizeof(*ContextRecord)); 00085 00086 return; 00087 } 00088 00089 VOID 00090 KdpSetStateChange ( 00091 IN PDBGKD_WAIT_STATE_CHANGE WaitStateChange, 00092 IN PEXCEPTION_RECORD ExceptionRecord, 00093 IN PCONTEXT ContextRecord, 00094 IN BOOLEAN SecondChance 00095 ) 00096 00097 /*++ 00098 00099 Routine Description: 00100 00101 Fill in the Wait_State_Change message record. 00102 00103 Arguments: 00104 00105 WaitStateChange - Supplies pointer to record to fill in 00106 00107 ExceptionRecord - Supplies a pointer to an exception record. 00108 00109 ContextRecord - Supplies a pointer to a context record. 00110 00111 SecondChance - Supplies a boolean value that determines whether this is 00112 the first or second chance for the exception. 00113 00114 Return Value: 00115 00116 None. 00117 00118 --*/ 00119 00120 { 00121 00122 ULONG Count; 00123 PVOID End; 00124 00125 // 00126 // Set up description of event, including exception record 00127 // 00128 00129 WaitStateChange->NewState = DbgKdExceptionStateChange; 00130 WaitStateChange->ProcessorLevel = KeProcessorLevel; 00131 WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number; 00132 WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors; 00133 WaitStateChange->Thread = (PVOID)KeGetCurrentThread(); 00134 WaitStateChange->ProgramCounter = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord); 00135 KdpQuickMoveMemory((PCHAR)&WaitStateChange->u.Exception.ExceptionRecord, 00136 (PCHAR)ExceptionRecord, 00137 sizeof(EXCEPTION_RECORD)); 00138 00139 WaitStateChange->u.Exception.FirstChance = !SecondChance; 00140 00141 // 00142 // Copy the immediate instruction stream into the control report structure. 00143 // 00144 00145 Count = KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00146 WaitStateChange->ProgramCounter, 00147 DBGKD_MAXSTREAM); 00148 00149 WaitStateChange->ControlReport.InstructionCount = (USHORT)Count; 00150 00151 // 00152 // Clear breakpoints in the copied instruction stream. If any breakpoints 00153 // are cleared, then recopy the instruction stream. 00154 // 00155 00156 End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1); 00157 if (KdpDeleteBreakpointRange(WaitStateChange->ProgramCounter, End) != FALSE) { 00158 KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00159 WaitStateChange->ProgramCounter, 00160 WaitStateChange->ControlReport.InstructionCount); 00161 } 00162 00163 // 00164 // Copy the context record into the wait state change structure. 00165 // 00166 00167 KdpMoveMemory((PCHAR)&WaitStateChange->Context, 00168 (PCHAR)ContextRecord, 00169 sizeof(*ContextRecord)); 00170 00171 return; 00172 } 00173 00174 VOID 00175 KdpGetStateChange ( 00176 IN PDBGKD_MANIPULATE_STATE ManipulateState, 00177 IN PCONTEXT ContextRecord 00178 ) 00179 00180 /*++ 00181 00182 Routine Description: 00183 00184 Extract continuation control data from Manipulate_State message 00185 00186 N.B. This is a noop for MIPS. 00187 00188 Arguments: 00189 00190 ManipulateState - supplies pointer to Manipulate_State packet 00191 00192 ContextRecord - Supplies a pointer to a context record. 00193 00194 Return Value: 00195 00196 None. 00197 00198 --*/ 00199 00200 { 00201 } 00202 00203 VOID 00204 KdpReadControlSpace ( 00205 IN PDBGKD_MANIPULATE_STATE m, 00206 IN PSTRING AdditionalData, 00207 IN PCONTEXT Context 00208 ) 00209 00210 /*++ 00211 00212 Routine Description: 00213 00214 This function is called in response of a read control space state 00215 manipulation message. Its function is to read implementation 00216 specific system data. 00217 00218 Arguments: 00219 00220 m - Supplies the state manipulation message. 00221 00222 AdditionalData - Supplies any additional data for the message. 00223 00224 Context - Supplies the current context. 00225 00226 Return Value: 00227 00228 None. 00229 00230 --*/ 00231 00232 { 00233 00234 PDBGKD_READ_MEMORY a = &m->u.ReadMemory; 00235 ULONG Length, t; 00236 PVOID StartAddr; 00237 STRING MessageHeader; 00238 PULONG EntryBuffer; 00239 00240 MessageHeader.Length = sizeof(*m); 00241 MessageHeader.Buffer = (PCHAR)m; 00242 00243 ASSERT(AdditionalData->Length == 0); 00244 00245 if (a->TransferCount > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE))) { 00246 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE); 00247 00248 } else { 00249 Length = a->TransferCount; 00250 } 00251 00252 // 00253 // Case on address to determine what part of Control space is being read. 00254 // 00255 00256 ASSERT(sizeof(PVOID) == sizeof(ULONG)); 00257 if ((ULONG)a->TargetBaseAddress == DEBUG_CONTROL_SPACE_PCR) { 00258 EntryBuffer = (PULONG)PCR; 00259 AdditionalData->Length = (USHORT)KdpMoveMemory( AdditionalData->Buffer, 00260 (PCHAR)&EntryBuffer, 00261 sizeof(ULONG) 00262 ); 00263 if (Length == AdditionalData->Length) { 00264 m->ReturnStatus = STATUS_SUCCESS; 00265 } else { 00266 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00267 } 00268 a->ActualBytesRead = sizeof(ULONG); 00269 } else if ((a->TargetBaseAddress < (PVOID)END_OF_CONTROL_SPACE) && 00270 (m->Processor < (USHORT)KeNumberProcessors)) { 00271 t = (PUCHAR)END_OF_CONTROL_SPACE - (PUCHAR)a->TargetBaseAddress; 00272 if (t < Length) { 00273 Length = t; 00274 } 00275 StartAddr = (PVOID)((ULONG)a->TargetBaseAddress + 00276 (ULONG)&(KiProcessorBlock[m->Processor]->ProcessorState)); 00277 AdditionalData->Length = (USHORT)KdpMoveMemory( 00278 AdditionalData->Buffer, 00279 StartAddr, 00280 Length 00281 ); 00282 00283 if (Length == AdditionalData->Length) { 00284 m->ReturnStatus = STATUS_SUCCESS; 00285 } else { 00286 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00287 } 00288 a->ActualBytesRead = AdditionalData->Length; 00289 00290 } else { 00291 00292 // 00293 // Uninterpreted Special Space 00294 // 00295 00296 AdditionalData->Length = 0; 00297 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00298 a->ActualBytesRead = 0; 00299 } 00300 00301 KdpSendPacket( 00302 PACKET_TYPE_KD_STATE_MANIPULATE, 00303 &MessageHeader, 00304 AdditionalData 00305 ); 00306 } 00307 00308 VOID 00309 KdpWriteControlSpace ( 00310 IN PDBGKD_MANIPULATE_STATE m, 00311 IN PSTRING AdditionalData, 00312 IN PCONTEXT Context 00313 ) 00314 00315 /*++ 00316 00317 Routine Description: 00318 00319 This function is called in response of a write control space state 00320 manipulation message. Its function is to write implementation 00321 specific system data. 00322 00323 Arguments: 00324 00325 m - Supplies the state manipulation message. 00326 00327 AdditionalData - Supplies any additional data for the message. 00328 00329 Context - Supplies the current context. 00330 00331 Return Value: 00332 00333 None. 00334 00335 --*/ 00336 00337 { 00338 PDBGKD_WRITE_MEMORY a = &m->u.WriteMemory; 00339 STRING MessageHeader; 00340 ULONG Length; 00341 PVOID StartAddr; 00342 00343 MessageHeader.Length = sizeof(*m); 00344 MessageHeader.Buffer = (PCHAR)m; 00345 00346 if ((((PUCHAR)a->TargetBaseAddress + a->TransferCount) <= 00347 (PUCHAR)END_OF_CONTROL_SPACE) && (m->Processor < (USHORT)KeNumberProcessors)) { 00348 00349 StartAddr = (PVOID)((ULONG)a->TargetBaseAddress + 00350 (ULONG)&(KiProcessorBlock[m->Processor]->ProcessorState)); 00351 00352 Length = KdpMoveMemory( 00353 StartAddr, 00354 AdditionalData->Buffer, 00355 AdditionalData->Length 00356 ); 00357 00358 if (Length == AdditionalData->Length) { 00359 m->ReturnStatus = STATUS_SUCCESS; 00360 } else { 00361 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00362 } 00363 a->ActualBytesWritten = Length; 00364 00365 } else { 00366 AdditionalData->Length = 0; 00367 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00368 a->ActualBytesWritten = 0; 00369 } 00370 00371 KdpSendPacket( 00372 PACKET_TYPE_KD_STATE_MANIPULATE, 00373 &MessageHeader, 00374 AdditionalData 00375 ); 00376 } 00377 00378 VOID 00379 KdpReadIoSpace ( 00380 IN PDBGKD_MANIPULATE_STATE m, 00381 IN PSTRING AdditionalData, 00382 IN PCONTEXT Context 00383 ) 00384 00385 /*++ 00386 00387 Routine Description: 00388 00389 This function is called in response of a read io space state 00390 manipulation message. Its function is to read system io 00391 locations. 00392 00393 Arguments: 00394 00395 m - Supplies the state manipulation message. 00396 00397 AdditionalData - Supplies any additional data for the message. 00398 00399 Context - Supplies the current context. 00400 00401 Return Value: 00402 00403 None. 00404 00405 --*/ 00406 00407 { 00408 PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo; 00409 STRING MessageHeader; 00410 PUCHAR b; 00411 PUSHORT s; 00412 PULONG l; 00413 00414 MessageHeader.Length = sizeof(*m); 00415 MessageHeader.Buffer = (PCHAR)m; 00416 00417 ASSERT(AdditionalData->Length == 0); 00418 00419 m->ReturnStatus = STATUS_SUCCESS; 00420 00421 // 00422 // Check Size and Alignment 00423 // 00424 00425 switch ( a->DataSize ) { 00426 case 1: 00427 b = (PUCHAR)MmDbgReadCheck(a->IoAddress); 00428 if ( b ) { 00429 a->DataValue = (ULONG)*b; 00430 } else { 00431 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00432 } 00433 break; 00434 case 2: 00435 if ((ULONG)a->IoAddress & 1 ) { 00436 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00437 } else { 00438 s = (PUSHORT)MmDbgReadCheck(a->IoAddress); 00439 if ( s ) { 00440 a->DataValue = (ULONG)*s; 00441 } else { 00442 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00443 } 00444 } 00445 break; 00446 case 4: 00447 if ((ULONG)a->IoAddress & 3 ) { 00448 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00449 } else { 00450 l = (PULONG)MmDbgReadCheck(a->IoAddress); 00451 if ( l ) { 00452 a->DataValue = (ULONG)*l; 00453 } else { 00454 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00455 } 00456 } 00457 break; 00458 default: 00459 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00460 } 00461 00462 KdpSendPacket( 00463 PACKET_TYPE_KD_STATE_MANIPULATE, 00464 &MessageHeader, 00465 NULL 00466 ); 00467 } 00468 00469 VOID 00470 KdpWriteIoSpace ( 00471 IN PDBGKD_MANIPULATE_STATE m, 00472 IN PSTRING AdditionalData, 00473 IN PCONTEXT Context 00474 ) 00475 00476 /*++ 00477 00478 Routine Description: 00479 00480 This function is called in response of a write io space state 00481 manipulation message. Its function is to write to system io 00482 locations. 00483 00484 Arguments: 00485 00486 m - Supplies the state manipulation message. 00487 00488 AdditionalData - Supplies any additional data for the message. 00489 00490 Context - Supplies the current context. 00491 00492 Return Value: 00493 00494 None. 00495 00496 --*/ 00497 00498 { 00499 PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo; 00500 STRING MessageHeader; 00501 PUCHAR b; 00502 PUSHORT s; 00503 PULONG l; 00504 00505 MessageHeader.Length = sizeof(*m); 00506 MessageHeader.Buffer = (PCHAR)m; 00507 00508 ASSERT(AdditionalData->Length == 0); 00509 00510 m->ReturnStatus = STATUS_SUCCESS; 00511 00512 // 00513 // Check Size and Alignment 00514 // 00515 00516 switch ( a->DataSize ) { 00517 case 1: 00518 b = (PUCHAR)MmDbgWriteCheck(a->IoAddress); 00519 if ( b ) { 00520 WRITE_REGISTER_UCHAR(b,(UCHAR)a->DataValue); 00521 } else { 00522 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00523 } 00524 break; 00525 case 2: 00526 if ((ULONG)a->IoAddress & 1 ) { 00527 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00528 } else { 00529 s = (PUSHORT)MmDbgWriteCheck(a->IoAddress); 00530 if ( s ) { 00531 WRITE_REGISTER_USHORT(s,(USHORT)a->DataValue); 00532 } else { 00533 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00534 } 00535 } 00536 break; 00537 case 4: 00538 if ((ULONG)a->IoAddress & 3 ) { 00539 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00540 } else { 00541 l = (PULONG)MmDbgWriteCheck(a->IoAddress); 00542 if ( l ) { 00543 WRITE_REGISTER_ULONG(l,a->DataValue); 00544 } else { 00545 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00546 } 00547 } 00548 break; 00549 default: 00550 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00551 } 00552 00553 KdpSendPacket( 00554 PACKET_TYPE_KD_STATE_MANIPULATE, 00555 &MessageHeader, 00556 NULL 00557 ); 00558 }

Generated on Sat May 15 19:40:34 2004 for test by doxygen 1.3.7