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_CHANGE64 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 (PCHAR)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 and restore the break- 00069 // points afterward. 00070 // 00071 00072 End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1); 00073 if (KdpSuspendBreakpointRange((PVOID)WaitStateChange->ProgramCounter, End) != FALSE) { 00074 KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00075 (PCHAR)WaitStateChange->ProgramCounter, 00076 WaitStateChange->ControlReport.InstructionCount); 00077 KdpRestoreBreakpointRange((PVOID)WaitStateChange->ProgramCounter, End); 00078 } 00079 00080 // 00081 // Copy the context record into the wait state change structure. 00082 // 00083 00084 KdpMoveMemory((PCHAR)&WaitStateChange->Context, 00085 (PCHAR)ContextRecord, 00086 sizeof(*ContextRecord)); 00087 00088 return; 00089 } 00090 00091 VOID 00092 KdpSetStateChange ( 00093 IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange, 00094 IN PEXCEPTION_RECORD ExceptionRecord, 00095 IN PCONTEXT ContextRecord, 00096 IN BOOLEAN SecondChance 00097 ) 00098 00099 /*++ 00100 00101 Routine Description: 00102 00103 Fill in the Wait_State_Change message record. 00104 00105 Arguments: 00106 00107 WaitStateChange - Supplies pointer to record to fill in 00108 00109 ExceptionRecord - Supplies a pointer to an exception record. 00110 00111 ContextRecord - Supplies a pointer to a context record. 00112 00113 SecondChance - Supplies a boolean value that determines whether this is 00114 the first or second chance for the exception. 00115 00116 Return Value: 00117 00118 None. 00119 00120 --*/ 00121 00122 { 00123 00124 ULONG Count; 00125 PVOID End; 00126 00127 // 00128 // Set up description of event, including exception record 00129 // 00130 00131 WaitStateChange->NewState = DbgKdExceptionStateChange; 00132 WaitStateChange->ProcessorLevel = KeProcessorLevel; 00133 WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number; 00134 WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors; 00135 WaitStateChange->Thread = (ULONG64)KeGetCurrentThread(); 00136 WaitStateChange->ProgramCounter = (ULONG64)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord); 00137 KdpQuickMoveMemory((PCHAR)&WaitStateChange->u.Exception.ExceptionRecord, 00138 (PCHAR)ExceptionRecord, 00139 sizeof(EXCEPTION_RECORD)); 00140 00141 WaitStateChange->u.Exception.FirstChance = !SecondChance; 00142 00143 // 00144 // Copy the immediate instruction stream into the control report structure. 00145 // 00146 00147 Count = KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00148 (PCHAR)WaitStateChange->ProgramCounter, 00149 DBGKD_MAXSTREAM); 00150 00151 WaitStateChange->ControlReport.InstructionCount = (USHORT)Count; 00152 00153 // 00154 // Clear breakpoints in the copied instruction stream. If any breakpoints 00155 // are cleared, then recopy the instruction stream and restore the break- 00156 // points afterward. 00157 // 00158 00159 End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1); 00160 if (KdpSuspendBreakpointRange((PVOID)WaitStateChange->ProgramCounter, End) != FALSE) { 00161 KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00162 (PCHAR)WaitStateChange->ProgramCounter, 00163 WaitStateChange->ControlReport.InstructionCount); 00164 KdpRestoreBreakpointRange((PVOID)WaitStateChange->ProgramCounter, End); 00165 } 00166 00167 // 00168 // Copy the context record into the wait state change structure. 00169 // 00170 00171 KdpMoveMemory((PCHAR)&WaitStateChange->Context, 00172 (PCHAR)ContextRecord, 00173 sizeof(*ContextRecord)); 00174 00175 return; 00176 } 00177 00178 VOID 00179 KdpGetStateChange ( 00180 IN PDBGKD_MANIPULATE_STATE64 ManipulateState, 00181 IN PCONTEXT ContextRecord 00182 ) 00183 00184 /*++ 00185 00186 Routine Description: 00187 00188 Extract continuation control data from Manipulate_State message 00189 00190 N.B. This is a noop for MIPS. 00191 00192 Arguments: 00193 00194 ManipulateState - supplies pointer to Manipulate_State packet 00195 00196 ContextRecord - Supplies a pointer to a context record. 00197 00198 Return Value: 00199 00200 None. 00201 00202 --*/ 00203 00204 { 00205 } 00206 00207 VOID 00208 KdpReadControlSpace ( 00209 IN PDBGKD_MANIPULATE_STATE64 m, 00210 IN PSTRING AdditionalData, 00211 IN PCONTEXT Context 00212 ) 00213 00214 /*++ 00215 00216 Routine Description: 00217 00218 This function is called in response of a read control space state 00219 manipulation message. Its function is to read implementation 00220 specific system data. 00221 00222 Arguments: 00223 00224 m - Supplies the state manipulation message. 00225 00226 AdditionalData - Supplies any additional data for the message. 00227 00228 Context - Supplies the current context. 00229 00230 Return Value: 00231 00232 None. 00233 00234 --*/ 00235 00236 { 00237 00238 PDBGKD_READ_MEMORY64 a = &m->u.ReadMemory; 00239 ULONG Length; 00240 STRING MessageHeader; 00241 PVOID Buffer = AdditionalData->Buffer; 00242 00243 MessageHeader.Length = sizeof(*m); 00244 MessageHeader.Buffer = (PCHAR)m; 00245 00246 ASSERT(AdditionalData->Length == 0); 00247 00248 if (a->TransferCount > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) { 00249 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); 00250 00251 } else { 00252 Length = a->TransferCount; 00253 } 00254 00255 // 00256 // Case on address to determine what part of Control space is being read. 00257 // 00258 00259 switch ( a->TargetBaseAddress ) { 00260 00261 // 00262 // Return the pcr address for the current processor. 00263 // 00264 00265 case DEBUG_CONTROL_SPACE_PCR: 00266 00267 *(PKPCR *)Buffer = (PKPCR)(KSEG3_BASE + 00268 (KiProcessorBlock[m->Processor]->PcrPage << PAGE_SHIFT)); 00269 AdditionalData->Length = sizeof( PKPCR ); 00270 a->ActualBytesRead = AdditionalData->Length; 00271 m->ReturnStatus = STATUS_SUCCESS; 00272 break; 00273 00274 // 00275 // Return the prcb address for the current processor. 00276 // 00277 00278 case DEBUG_CONTROL_SPACE_PRCB: 00279 00280 *(PKPRCB *)Buffer = KiProcessorBlock[m->Processor]; 00281 AdditionalData->Length = sizeof( PKPRCB ); 00282 a->ActualBytesRead = AdditionalData->Length; 00283 m->ReturnStatus = STATUS_SUCCESS; 00284 break; 00285 00286 // 00287 // Return the pointer to the current thread address for the 00288 // current processor. 00289 // 00290 00291 case DEBUG_CONTROL_SPACE_THREAD: 00292 00293 *(PKTHREAD *)Buffer = KiProcessorBlock[m->Processor]->CurrentThread; 00294 AdditionalData->Length = sizeof( PKTHREAD ); 00295 a->ActualBytesRead = AdditionalData->Length; 00296 m->ReturnStatus = STATUS_SUCCESS; 00297 break; 00298 00299 00300 case DEBUG_CONTROL_SPACE_KSPECIAL: 00301 00302 KdpMoveMemory (Buffer, 00303 (PVOID)&(KiProcessorBlock[m->Processor]->ProcessorState.SpecialRegisters), 00304 sizeof( KSPECIAL_REGISTERS ) 00305 ); 00306 AdditionalData->Length = sizeof( KSPECIAL_REGISTERS ); 00307 a->ActualBytesRead = AdditionalData->Length; 00308 m->ReturnStatus = STATUS_SUCCESS; 00309 break; 00310 00311 default: 00312 00313 AdditionalData->Length = 0; 00314 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00315 a->ActualBytesRead = 0; 00316 00317 } 00318 00319 KdpSendPacket( 00320 PACKET_TYPE_KD_STATE_MANIPULATE, 00321 &MessageHeader, 00322 AdditionalData 00323 ); 00324 } 00325 00326 VOID 00327 KdpWriteControlSpace ( 00328 IN PDBGKD_MANIPULATE_STATE64 m, 00329 IN PSTRING AdditionalData, 00330 IN PCONTEXT Context 00331 ) 00332 00333 /*++ 00334 00335 Routine Description: 00336 00337 This function is called in response of a write control space state 00338 manipulation message. Its function is to write implementation 00339 specific system data. 00340 00341 Arguments: 00342 00343 m - Supplies the state manipulation message. 00344 00345 AdditionalData - Supplies any additional data for the message. 00346 00347 Context - Supplies the current context. 00348 00349 Return Value: 00350 00351 None. 00352 00353 --*/ 00354 00355 { 00356 PDBGKD_WRITE_MEMORY64 a = &m->u.WriteMemory; 00357 STRING MessageHeader; 00358 ULONG Length; 00359 PVOID Buffer = AdditionalData->Buffer; 00360 00361 MessageHeader.Length = sizeof(*m); 00362 MessageHeader.Buffer = (PCHAR)m; 00363 00364 switch ( (ULONG_PTR)a->TargetBaseAddress ) { 00365 00366 case DEBUG_CONTROL_SPACE_KSPECIAL: 00367 00368 KdpMoveMemory ((PVOID)&(KiProcessorBlock[m->Processor]->ProcessorState.SpecialRegisters), 00369 Buffer, 00370 sizeof( KSPECIAL_REGISTERS ) 00371 ); 00372 AdditionalData->Length = sizeof( KSPECIAL_REGISTERS ); 00373 a->ActualBytesWritten = AdditionalData->Length; 00374 m->ReturnStatus = STATUS_SUCCESS; 00375 break; 00376 00377 default: 00378 00379 AdditionalData->Length = 0; 00380 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00381 a->ActualBytesWritten = 0; 00382 00383 } 00384 00385 KdpSendPacket( 00386 PACKET_TYPE_KD_STATE_MANIPULATE, 00387 &MessageHeader, 00388 AdditionalData 00389 ); 00390 } 00391 00392 VOID 00393 KdpReadIoSpace ( 00394 IN PDBGKD_MANIPULATE_STATE64 m, 00395 IN PSTRING AdditionalData, 00396 IN PCONTEXT Context 00397 ) 00398 00399 /*++ 00400 00401 Routine Description: 00402 00403 This function is called in response of a read io space state 00404 manipulation message. Its function is to read system io 00405 locations. 00406 00407 Arguments: 00408 00409 m - Supplies the state manipulation message. 00410 00411 AdditionalData - Supplies any additional data for the message. 00412 00413 Context - Supplies the current context. 00414 00415 Return Value: 00416 00417 None. 00418 00419 --*/ 00420 00421 { 00422 PDBGKD_READ_WRITE_IO64 a = &m->u.ReadWriteIo; 00423 STRING MessageHeader; 00424 PUCHAR b; 00425 PUSHORT s; 00426 PULONG l; 00427 00428 MessageHeader.Length = sizeof(*m); 00429 MessageHeader.Buffer = (PCHAR)m; 00430 00431 ASSERT(AdditionalData->Length == 0); 00432 00433 m->ReturnStatus = STATUS_SUCCESS; 00434 00435 // 00436 // Check Size and Alignment 00437 // 00438 00439 switch ( a->DataSize ) { 00440 case 1: 00441 b = (PUCHAR)MmDbgReadCheck((PVOID)a->IoAddress); 00442 if ( b ) { 00443 a->DataValue = (ULONG)*b; 00444 } else { 00445 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00446 } 00447 break; 00448 case 2: 00449 if ((ULONG_PTR)a->IoAddress & 1 ) { 00450 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00451 } else { 00452 s = (PUSHORT)MmDbgReadCheck((PVOID)a->IoAddress); 00453 if ( s ) { 00454 a->DataValue = (ULONG)*s; 00455 } else { 00456 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00457 } 00458 } 00459 break; 00460 case 4: 00461 if ((ULONG_PTR)a->IoAddress & 3 ) { 00462 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00463 } else { 00464 l = (PULONG)MmDbgReadCheck((PVOID)a->IoAddress); 00465 if ( l ) { 00466 a->DataValue = (ULONG)*l; 00467 } else { 00468 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00469 } 00470 } 00471 break; 00472 default: 00473 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00474 } 00475 00476 KdpSendPacket( 00477 PACKET_TYPE_KD_STATE_MANIPULATE, 00478 &MessageHeader, 00479 NULL 00480 ); 00481 } 00482 00483 VOID 00484 KdpWriteIoSpace ( 00485 IN PDBGKD_MANIPULATE_STATE64 m, 00486 IN PSTRING AdditionalData, 00487 IN PCONTEXT Context 00488 ) 00489 00490 /*++ 00491 00492 Routine Description: 00493 00494 This function is called in response of a write io space state 00495 manipulation message. Its function is to write to system io 00496 locations. 00497 00498 Arguments: 00499 00500 m - Supplies the state manipulation message. 00501 00502 AdditionalData - Supplies any additional data for the message. 00503 00504 Context - Supplies the current context. 00505 00506 Return Value: 00507 00508 None. 00509 00510 --*/ 00511 00512 { 00513 PDBGKD_READ_WRITE_IO64 a = &m->u.ReadWriteIo; 00514 STRING MessageHeader; 00515 PUCHAR b; 00516 PUSHORT s; 00517 PULONG l; 00518 HARDWARE_PTE Opaque; 00519 00520 MessageHeader.Length = sizeof(*m); 00521 MessageHeader.Buffer = (PCHAR)m; 00522 00523 ASSERT(AdditionalData->Length == 0); 00524 00525 m->ReturnStatus = STATUS_SUCCESS; 00526 00527 // 00528 // Check Size and Alignment 00529 // 00530 00531 switch ( a->DataSize ) { 00532 case 1: 00533 b = (PUCHAR)MmDbgWriteCheck((PVOID)a->IoAddress, &Opaque); 00534 if ( b ) { 00535 WRITE_REGISTER_UCHAR(b,(UCHAR)a->DataValue); 00536 MmDbgReleaseAddress(b, &Opaque); 00537 } else { 00538 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00539 } 00540 break; 00541 case 2: 00542 if ((ULONG_PTR)a->IoAddress & 1 ) { 00543 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00544 } else { 00545 s = (PUSHORT)MmDbgWriteCheck((PVOID)a->IoAddress, &Opaque); 00546 if ( s ) { 00547 WRITE_REGISTER_USHORT(s,(USHORT)a->DataValue); 00548 MmDbgReleaseAddress(s, &Opaque); 00549 } else { 00550 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00551 } 00552 } 00553 break; 00554 case 4: 00555 if ((ULONG_PTR)a->IoAddress & 3 ) { 00556 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00557 } else { 00558 l = (PULONG)MmDbgWriteCheck((PVOID)a->IoAddress, &Opaque); 00559 if ( l ) { 00560 WRITE_REGISTER_ULONG(l,a->DataValue); 00561 MmDbgReleaseAddress(l, &Opaque); 00562 } else { 00563 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00564 } 00565 } 00566 break; 00567 default: 00568 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00569 } 00570 00571 KdpSendPacket( 00572 PACKET_TYPE_KD_STATE_MANIPULATE, 00573 &MessageHeader, 00574 NULL 00575 ); 00576 }

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