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 Mark Lucovsky (markl) 04-Sep-1990 00016 00017 Revision History: 00018 00019 --*/ 00020 00021 #include "kdp.h" 00022 00023 00024 #define HEADER_FILE 00025 #include "kxmips.h" 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 Count); 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 Count); 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; 00236 STRING MessageHeader; 00237 ULONG NumberOfEntries; 00238 ULONG StartingEntry; 00239 PULONG EntryBuffer; 00240 PKPRCB Prcb; 00241 PTB_ENTRY TbEntry; 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_STATE))) { 00249 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE); 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 ASSERT(sizeof(PVOID) == sizeof(ULONG)); 00260 if ( (ULONG)a->TargetBaseAddress >= 0 && 00261 (ULONG)a->TargetBaseAddress < KeNumberTbEntries && 00262 (m->Processor < (USHORT)KeNumberProcessors )) { 00263 00264 // 00265 // Read TB entries. 00266 // 00267 00268 NumberOfEntries = Length / sizeof(TB_ENTRY); 00269 StartingEntry = (ULONG)a->TargetBaseAddress; 00270 00271 // 00272 // Trim number of entries to tb range 00273 // 00274 00275 if (StartingEntry + NumberOfEntries > KeNumberTbEntries) { 00276 NumberOfEntries = KeNumberTbEntries - StartingEntry; 00277 } 00278 00279 AdditionalData->Length = (USHORT)(NumberOfEntries * sizeof(TB_ENTRY)); 00280 EntryBuffer = (PULONG)AdditionalData->Buffer; 00281 Prcb = KiProcessorBlock[m->Processor]; 00282 TbEntry = &Prcb->ProcessorState.TbEntry[0]; 00283 while (NumberOfEntries--) { 00284 *(PENTRYLO)EntryBuffer++ = TbEntry[StartingEntry].Entrylo0; 00285 *(PENTRYLO)EntryBuffer++ = TbEntry[StartingEntry].Entrylo1; 00286 *(PENTRYHI)EntryBuffer++ = TbEntry[StartingEntry].Entryhi; 00287 *(PPAGEMASK)EntryBuffer++ = TbEntry[StartingEntry].Pagemask; 00288 StartingEntry += 1; 00289 } 00290 00291 m->ReturnStatus = STATUS_SUCCESS; 00292 a->ActualBytesRead = AdditionalData->Length; 00293 00294 } else { 00295 00296 // 00297 // Uninterpreted Special Space 00298 // 00299 00300 AdditionalData->Length = 0; 00301 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00302 a->ActualBytesRead = 0; 00303 } 00304 00305 KdpSendPacket( 00306 PACKET_TYPE_KD_STATE_MANIPULATE, 00307 &MessageHeader, 00308 AdditionalData 00309 ); 00310 } 00311 00312 VOID 00313 KdpWriteControlSpace ( 00314 IN PDBGKD_MANIPULATE_STATE m, 00315 IN PSTRING AdditionalData, 00316 IN PCONTEXT Context 00317 ) 00318 00319 /*++ 00320 00321 Routine Description: 00322 00323 This function is called in response of a write control space state 00324 manipulation message. Its function is to write implementation 00325 specific system data. 00326 00327 Arguments: 00328 00329 m - Supplies the state manipulation message. 00330 00331 AdditionalData - Supplies any additional data for the message. 00332 00333 Context - Supplies the current context. 00334 00335 Return Value: 00336 00337 None. 00338 00339 --*/ 00340 00341 { 00342 PDBGKD_WRITE_MEMORY a = &m->u.WriteMemory; 00343 STRING MessageHeader; 00344 00345 MessageHeader.Length = sizeof(*m); 00346 MessageHeader.Buffer = (PCHAR)m; 00347 00348 AdditionalData->Length = 0; 00349 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00350 a->ActualBytesWritten = 0; 00351 00352 KdpSendPacket( 00353 PACKET_TYPE_KD_STATE_MANIPULATE, 00354 &MessageHeader, 00355 AdditionalData 00356 ); 00357 } 00358 00359 VOID 00360 KdpReadIoSpace ( 00361 IN PDBGKD_MANIPULATE_STATE m, 00362 IN PSTRING AdditionalData, 00363 IN PCONTEXT Context 00364 ) 00365 00366 /*++ 00367 00368 Routine Description: 00369 00370 This function is called in response of a read io space state 00371 manipulation message. Its function is to read system io 00372 locations. 00373 00374 Arguments: 00375 00376 m - Supplies the state manipulation message. 00377 00378 AdditionalData - Supplies any additional data for the message. 00379 00380 Context - Supplies the current context. 00381 00382 Return Value: 00383 00384 None. 00385 00386 --*/ 00387 00388 { 00389 PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo; 00390 STRING MessageHeader; 00391 PUCHAR b; 00392 PUSHORT s; 00393 PULONG l; 00394 00395 MessageHeader.Length = sizeof(*m); 00396 MessageHeader.Buffer = (PCHAR)m; 00397 00398 ASSERT(AdditionalData->Length == 0); 00399 00400 m->ReturnStatus = STATUS_SUCCESS; 00401 00402 // 00403 // Check Size and Alignment 00404 // 00405 00406 switch ( a->DataSize ) { 00407 case 1: 00408 b = (PUCHAR)MmDbgReadCheck(a->IoAddress); 00409 if ( b ) { 00410 a->DataValue = (ULONG)*b; 00411 } else { 00412 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00413 } 00414 break; 00415 case 2: 00416 if ((ULONG)a->IoAddress & 1 ) { 00417 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00418 } else { 00419 s = (PUSHORT)MmDbgReadCheck(a->IoAddress); 00420 if ( s ) { 00421 a->DataValue = (ULONG)*s; 00422 } else { 00423 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00424 } 00425 } 00426 break; 00427 case 4: 00428 if ((ULONG)a->IoAddress & 3 ) { 00429 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00430 } else { 00431 l = (PULONG)MmDbgReadCheck(a->IoAddress); 00432 if ( l ) { 00433 a->DataValue = (ULONG)*l; 00434 } else { 00435 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00436 } 00437 } 00438 break; 00439 default: 00440 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00441 } 00442 00443 KdpSendPacket( 00444 PACKET_TYPE_KD_STATE_MANIPULATE, 00445 &MessageHeader, 00446 NULL 00447 ); 00448 } 00449 00450 VOID 00451 KdpWriteIoSpace ( 00452 IN PDBGKD_MANIPULATE_STATE m, 00453 IN PSTRING AdditionalData, 00454 IN PCONTEXT Context 00455 ) 00456 00457 /*++ 00458 00459 Routine Description: 00460 00461 This function is called in response of a write io space state 00462 manipulation message. Its function is to write to system io 00463 locations. 00464 00465 Arguments: 00466 00467 m - Supplies the state manipulation message. 00468 00469 AdditionalData - Supplies any additional data for the message. 00470 00471 Context - Supplies the current context. 00472 00473 Return Value: 00474 00475 None. 00476 00477 --*/ 00478 00479 { 00480 PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo; 00481 STRING MessageHeader; 00482 PUCHAR b; 00483 PUSHORT s; 00484 PULONG l; 00485 00486 MessageHeader.Length = sizeof(*m); 00487 MessageHeader.Buffer = (PCHAR)m; 00488 00489 ASSERT(AdditionalData->Length == 0); 00490 00491 m->ReturnStatus = STATUS_SUCCESS; 00492 00493 // 00494 // Check Size and Alignment 00495 // 00496 00497 switch ( a->DataSize ) { 00498 case 1: 00499 b = (PUCHAR)MmDbgWriteCheck(a->IoAddress); 00500 if ( b ) { 00501 WRITE_REGISTER_UCHAR(b,(UCHAR)a->DataValue); 00502 } else { 00503 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00504 } 00505 break; 00506 case 2: 00507 if ((ULONG)a->IoAddress & 1 ) { 00508 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00509 } else { 00510 s = (PUSHORT)MmDbgWriteCheck(a->IoAddress); 00511 if ( s ) { 00512 WRITE_REGISTER_USHORT(s,(USHORT)a->DataValue); 00513 } else { 00514 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00515 } 00516 } 00517 break; 00518 case 4: 00519 if ((ULONG)a->IoAddress & 3 ) { 00520 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00521 } else { 00522 l = (PULONG)MmDbgWriteCheck(a->IoAddress); 00523 if ( l ) { 00524 WRITE_REGISTER_ULONG(l,a->DataValue); 00525 } else { 00526 m->ReturnStatus = STATUS_ACCESS_VIOLATION; 00527 } 00528 } 00529 break; 00530 default: 00531 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00532 } 00533 00534 KdpSendPacket( 00535 PACKET_TYPE_KD_STATE_MANIPULATE, 00536 &MessageHeader, 00537 NULL 00538 ); 00539 }

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