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 Copyright (c) 1992 Digital Equipment Corporation 00005 00006 Module Name: 00007 00008 kdcpuapi.c 00009 00010 Abstract: 00011 00012 This module implements CPU specific remote debug APIs. 00013 00014 Author: 00015 00016 Mark Lucovsky (markl) 04-Sep-1990 00017 00018 Revision History: 00019 00020 Jeff McLeman (mcleman) 11-June-1992 00021 Make this an alpha specific module 00022 00023 Joe Notarangelo 28-Sep-1992 00024 Add Alpha-specific control space semantics. 00025 00026 Miche Baker-Harvey 22-Oct-1992 00027 Added Kdp{Read,Write}IoSpace 00028 --*/ 00029 00030 #include "kdp.h" 00031 00032 #define HEADER_FILE 00033 #include "kxalpha.h" 00034 00035 VOID 00036 KdpSetLoadState ( 00037 IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange, 00038 IN PCONTEXT ContextRecord 00039 ) 00040 00041 /*++ 00042 00043 Routine Description: 00044 00045 Fill in the Wait_State_Change message record for the load symbol case. 00046 00047 Arguments: 00048 00049 WaitStateChange - Supplies pointer to record to fill in 00050 00051 ContextRecord - Supplies a pointer to a context record. 00052 00053 Return Value: 00054 00055 None. 00056 00057 --*/ 00058 00059 { 00060 00061 ULONG Count; 00062 PVOID End; 00063 00064 // 00065 // Copy the immediate instruction stream into the control report structure. 00066 // 00067 00068 Count = KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00069 (PCHAR)WaitStateChange->ProgramCounter, 00070 DBGKD_MAXSTREAM); 00071 00072 WaitStateChange->ControlReport.InstructionCount = (USHORT)Count; 00073 00074 // 00075 // Clear breakpoints in the copied instruction stream. If any breakpoints 00076 // are clear, then recopy the instruction strasm. 00077 // 00078 00079 End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1); 00080 if (KdpDeleteBreakpointRange((PVOID)WaitStateChange->ProgramCounter, End) != FALSE) { 00081 KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00082 (PVOID)WaitStateChange->ProgramCounter, 00083 Count); 00084 } 00085 00086 // 00087 // Copy the context record into the wait state structure. 00088 // 00089 00090 KdpMoveMemory((PCHAR)&WaitStateChange->Context, 00091 (PCHAR)ContextRecord, 00092 sizeof(*ContextRecord)); 00093 00094 return; 00095 } 00096 00097 VOID 00098 KdpSetStateChange ( 00099 IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange, 00100 IN PEXCEPTION_RECORD ExceptionRecord, 00101 IN PCONTEXT ContextRecord, 00102 IN BOOLEAN SecondChance 00103 ) 00104 00105 /*++ 00106 00107 Routine Description: 00108 00109 Fill in the Wait_State_Change message record. 00110 00111 Arguments: 00112 00113 WaitStateChange - Supplies pointer to record to fill in 00114 00115 ExceptionRecord - Supplies a pointer to an exception record. 00116 00117 ContextRecord - Supplies a pointer to a context record. 00118 00119 SecondChance - Supplies a boolean value that determines whether this is 00120 the first or second chance for the exception. 00121 00122 Return Value: 00123 00124 None. 00125 00126 --*/ 00127 00128 { 00129 00130 ULONG Count; 00131 PVOID End; 00132 00133 // 00134 // Set up description of event, including exception record 00135 // 00136 00137 WaitStateChange->NewState = DbgKdExceptionStateChange; 00138 WaitStateChange->ProcessorLevel = KeProcessorLevel; 00139 WaitStateChange->Processor = (USHORT)KdpGetCurrentPrcb()->Number; 00140 WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors; 00141 WaitStateChange->Thread = (ULONG_PTR)KdpGetCurrentThread(); 00142 WaitStateChange->ProgramCounter = (ULONG_PTR)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord); 00143 if (sizeof(EXCEPTION_RECORD) == sizeof(WaitStateChange->u.Exception.ExceptionRecord)) { 00144 KdpQuickMoveMemory((PCHAR)&WaitStateChange->u.Exception.ExceptionRecord, 00145 (PCHAR)ExceptionRecord, 00146 sizeof(EXCEPTION_RECORD)); 00147 } else { 00148 ExceptionRecord32To64((PEXCEPTION_RECORD32)ExceptionRecord, 00149 &WaitStateChange->u.Exception.ExceptionRecord 00150 ); 00151 } 00152 00153 WaitStateChange->u.Exception.FirstChance = !SecondChance; 00154 00155 // 00156 // Copy the immediate instruction stream into the control report structure. 00157 // 00158 00159 Count = KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00160 (PVOID)WaitStateChange->ProgramCounter, 00161 DBGKD_MAXSTREAM); 00162 00163 WaitStateChange->ControlReport.InstructionCount = (USHORT)Count; 00164 00165 // 00166 // Clear breakpoints in the copied instruction stream. If any breakpoints 00167 // are clear, then recopy the instruction strasm. 00168 // 00169 00170 End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1); 00171 if (KdpDeleteBreakpointRange((PVOID)WaitStateChange->ProgramCounter, End) != FALSE) { 00172 KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00173 (PVOID)WaitStateChange->ProgramCounter, 00174 Count); 00175 } 00176 00177 // 00178 // Copy the context record into the wait state structure. 00179 // 00180 00181 KdpMoveMemory((PCHAR)&WaitStateChange->Context, 00182 (PCHAR)ContextRecord, 00183 sizeof(*ContextRecord)); 00184 00185 return; 00186 } 00187 00188 VOID 00189 KdpGetStateChange ( 00190 IN PDBGKD_MANIPULATE_STATE64 ManipulateState, 00191 IN PCONTEXT ContextRecord 00192 ) 00193 00194 /*++ 00195 00196 Routine Description: 00197 00198 Extract continuation control data from Manipulate_State message 00199 00200 N.B. This is a noop for MIPS. 00201 00202 Arguments: 00203 00204 ManipulateState - supplies pointer to Manipulate_State packet 00205 00206 ContextRecord - Supplies a pointer to a context record. 00207 00208 Return Value: 00209 00210 None. 00211 00212 --*/ 00213 00214 { 00215 } 00216 00217 VOID 00218 KdpReadControlSpace ( 00219 IN PDBGKD_MANIPULATE_STATE64 m, 00220 IN PSTRING AdditionalData, 00221 IN PCONTEXT Context 00222 ) 00223 00224 /*++ 00225 00226 Routine Description: 00227 00228 This function is called in response of a read control space state 00229 manipulation message. Its function is to read implementation 00230 specific system data. 00231 00232 Arguments: 00233 00234 m - Supplies the state manipulation message. 00235 00236 AdditionalData - Supplies any additional data for the message. 00237 00238 Context - Supplies the current context. 00239 00240 Return Value: 00241 00242 None. 00243 00244 --*/ 00245 00246 { 00247 00248 PDBGKD_READ_MEMORY64 a = &m->u.ReadMemory; 00249 ULONG Length; 00250 STRING MessageHeader; 00251 PVOID Buffer = AdditionalData->Buffer; 00252 00253 MessageHeader.Length = sizeof(*m); 00254 MessageHeader.Buffer = (PCHAR)m; 00255 00256 ASSERT(AdditionalData->Length == 0); 00257 00258 if (a->TransferCount > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) { 00259 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); 00260 } else { 00261 Length = a->TransferCount; 00262 } 00263 00264 ASSERT(sizeof(PVOID) == sizeof(ULONG_PTR)); 00265 00266 //NOTENOTE 00267 // This code will in fact only work on a uni-processor as the 00268 // m->Processor field is ignored for now 00269 00270 // 00271 // Case on address to determine what part of Control 00272 // space is being read 00273 // 00274 00275 switch( (ULONG_PTR)a->TargetBaseAddress ){ 00276 00277 // 00278 // Return the pcr address for the current processor. 00279 // 00280 00281 case DEBUG_CONTROL_SPACE_PCR: 00282 00283 *(PKPCR *)Buffer = KdpGetPcr(); 00284 AdditionalData->Length = sizeof( PKPCR ); 00285 a->ActualBytesRead = AdditionalData->Length; 00286 m->ReturnStatus = STATUS_SUCCESS; 00287 break; 00288 00289 // 00290 // Return the prcb address for the current processor. 00291 // 00292 00293 case DEBUG_CONTROL_SPACE_PRCB: 00294 00295 *(PKPRCB *)Buffer = KdpGetCurrentPrcb(); 00296 AdditionalData->Length = sizeof( PKPRCB ); 00297 a->ActualBytesRead = AdditionalData->Length; 00298 m->ReturnStatus = STATUS_SUCCESS; 00299 break; 00300 00301 // 00302 // Return the pointer to the current thread address for the 00303 // current processor. 00304 // 00305 00306 case DEBUG_CONTROL_SPACE_THREAD: 00307 00308 *(PKTHREAD *)Buffer = KdpGetCurrentThread(); 00309 AdditionalData->Length = sizeof( PKTHREAD ); 00310 a->ActualBytesRead = AdditionalData->Length; 00311 m->ReturnStatus = STATUS_SUCCESS; 00312 break; 00313 00314 // 00315 // Return the current Thread Environment Block pointer for the 00316 // current thread on the current processor. 00317 // 00318 00319 case DEBUG_CONTROL_SPACE_TEB: 00320 00321 *(PVOID *)Buffer = (PVOID)NtCurrentTeb(); 00322 AdditionalData->Length = sizeof( struct _TEB * ); 00323 a->ActualBytesRead = AdditionalData->Length; 00324 m->ReturnStatus = STATUS_SUCCESS; 00325 break; 00326 00327 // 00328 // Return the dpc active flag for the current processor. 00329 // 00330 00331 case DEBUG_CONTROL_SPACE_DPCACTIVE: 00332 00333 *(BOOLEAN *)Buffer = KeIsExecutingDpc(); 00334 AdditionalData->Length = sizeof( ULONG ); 00335 a->ActualBytesRead = AdditionalData->Length; 00336 m->ReturnStatus = STATUS_SUCCESS; 00337 break; 00338 00339 // 00340 // Return the internal processor register state. 00341 // 00342 // N.B. - the kernel debugger buffer is expected to be allocated 00343 // in the 32-bit superpage 00344 // 00345 // N.B. - the size of the internal state cannot exceed the size of 00346 // the buffer allocated to the kernel debugger via 00347 // KDP_MESSAGE_BUFFER_SIZE 00348 // 00349 00350 case DEBUG_CONTROL_SPACE_IPRSTATE: 00351 00352 // 00353 // Guarantee that Buffer is quadword-aligned, and adjust the 00354 // size of the available buffer accordingly. 00355 // 00356 00357 Buffer = (PVOID)( ((ULONG_PTR)Buffer + 7) & ~7); 00358 00359 Length = (ULONG)((ULONG_PTR)&AdditionalData->Buffer[KDP_MESSAGE_BUFFER_SIZE] - 00360 (ULONG_PTR)Buffer); 00361 00362 AdditionalData->Length = (USHORT)KdpReadInternalProcessorState( 00363 Buffer, 00364 Length ); 00365 00366 // 00367 // Check the returned size, if greater than the buffer size than 00368 // we didn't have a sufficient buffer. If zero then the call 00369 // failed otherwise. 00370 // 00371 00372 if( (AdditionalData->Length > KDP_MESSAGE_BUFFER_SIZE) || 00373 (AdditionalData->Length == 0) ){ 00374 00375 AdditionalData->Length = 0; 00376 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00377 a->ActualBytesRead = 0; 00378 00379 } else { 00380 00381 m->ReturnStatus = STATUS_SUCCESS; 00382 a->ActualBytesRead = AdditionalData->Length; 00383 00384 } 00385 00386 break; 00387 00388 // 00389 // Return the internal processor counter values. 00390 // 00391 // N.B. - the kernel debugger buffer is expected to be allocated 00392 // in the 32-bit superpage 00393 // 00394 // N.B. - the size of the counters structure cannot exceed the size of 00395 // the buffer allocated to the kernel debugger via 00396 // KDP_MESSAGE_BUFFER_SIZE 00397 // 00398 00399 case DEBUG_CONTROL_SPACE_COUNTERS: 00400 00401 // 00402 // Guarantee that Buffer is quadword-aligned, and adjust the 00403 // size of the available buffer accordingly. 00404 // 00405 00406 Buffer = (PVOID)( ((ULONG_PTR)Buffer + 7) & ~7); 00407 00408 Length = (ULONG)((ULONG_PTR)&AdditionalData->Buffer[KDP_MESSAGE_BUFFER_SIZE] - 00409 (ULONG_PTR)Buffer); 00410 00411 AdditionalData->Length = (USHORT)KdpReadInternalProcessorCounters( 00412 Buffer, 00413 Length ); 00414 00415 // 00416 // Check the returned size, if greater than the buffer size than 00417 // we didn't have a sufficient buffer. If zero then the call 00418 // failed otherwise. 00419 // 00420 00421 if( (AdditionalData->Length > KDP_MESSAGE_BUFFER_SIZE) || 00422 (AdditionalData->Length == 0) ){ 00423 00424 AdditionalData->Length = 0; 00425 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00426 a->ActualBytesRead = 0; 00427 00428 } else { 00429 00430 m->ReturnStatus = STATUS_SUCCESS; 00431 a->ActualBytesRead = AdditionalData->Length; 00432 00433 } 00434 00435 break; 00436 00437 // 00438 // Uninterpreted Special Space 00439 // 00440 00441 default: 00442 00443 AdditionalData->Length = 0; 00444 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00445 a->ActualBytesRead = 0; 00446 00447 } 00448 00449 KdpSendPacket( 00450 PACKET_TYPE_KD_STATE_MANIPULATE, 00451 &MessageHeader, 00452 AdditionalData 00453 ); 00454 } 00455 00456 VOID 00457 KdpWriteControlSpace ( 00458 IN PDBGKD_MANIPULATE_STATE64 m, 00459 IN PSTRING AdditionalData, 00460 IN PCONTEXT Context 00461 ) 00462 00463 /*++ 00464 00465 Routine Description: 00466 00467 This function is called in response of a write control space state 00468 manipulation message. Its function is to write implementation 00469 specific system data. 00470 00471 Arguments: 00472 00473 m - Supplies the state manipulation message. 00474 00475 AdditionalData - Supplies any additional data for the message. 00476 00477 Context - Supplies the current context. 00478 00479 Return Value: 00480 00481 None. 00482 00483 --*/ 00484 00485 { 00486 PDBGKD_WRITE_MEMORY64 a = &m->u.WriteMemory; 00487 ULONG Length; 00488 STRING MessageHeader; 00489 00490 MessageHeader.Length = sizeof(*m); 00491 MessageHeader.Buffer = (PCHAR)m; 00492 00493 AdditionalData->Length = 0; 00494 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00495 a->ActualBytesWritten = 0; 00496 00497 KdpSendPacket( 00498 PACKET_TYPE_KD_STATE_MANIPULATE, 00499 &MessageHeader, 00500 AdditionalData 00501 ); 00502 } 00503 00504 VOID 00505 KdpReadIoSpace ( 00506 IN PDBGKD_MANIPULATE_STATE64 m, 00507 IN PSTRING AdditionalData, 00508 IN PCONTEXT Context 00509 ) 00510 00511 /*++ 00512 00513 Routine Description: 00514 00515 This function is called in response of a read io space state 00516 manipulation message. Its function is to read system io 00517 locations. 00518 00519 Arguments: 00520 00521 m - Supplies the state manipulation message. 00522 00523 AdditionalData - Supplies any additional data for the message. 00524 00525 Context - Supplies the current context. 00526 00527 Return Value: 00528 00529 None. 00530 00531 --*/ 00532 00533 { 00534 PDBGKD_READ_WRITE_IO64 a = &m->u.ReadWriteIo; 00535 STRING MessageHeader; 00536 INTERFACE_TYPE InterfaceType; 00537 ULONG BusNumber; 00538 PHYSICAL_ADDRESS IoAddress; 00539 PHYSICAL_ADDRESS TranslatedAddress; 00540 ULONG AddressSpace; 00541 ULONG DataSize; 00542 00543 MessageHeader.Length = sizeof(*m); 00544 MessageHeader.Buffer = (PCHAR)m; 00545 00546 ASSERT(AdditionalData->Length == 0); 00547 00548 m->ReturnStatus = STATUS_SUCCESS; 00549 00550 // 00551 // Capture the input parameters and use the default values for those 00552 // parameters not specified in the Api. 00553 // 00554 00555 InterfaceType = Isa; 00556 BusNumber = 0; 00557 AddressSpace = 1; 00558 IoAddress.QuadPart = (ULONG_PTR)a->IoAddress; 00559 DataSize = a->DataSize; 00560 00561 // 00562 // Zero the return data value. 00563 // 00564 00565 a->DataValue = 0; 00566 00567 // 00568 // Translate the bus address to the physical system address 00569 // or QVA. 00570 // 00571 00572 if( !HalTranslateBusAddress( InterfaceType, 00573 BusNumber, 00574 IoAddress, 00575 &AddressSpace, 00576 &TranslatedAddress ) ){ 00577 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00578 goto SendReadIoSpaceResponse; 00579 } 00580 00581 // 00582 // N.B. - for the moment we will only support QVAs ie. when AddressSpace 00583 // is one. It may be in later systems that we will have to 00584 // check the address space, map it, perform the virtual read 00585 // unmap, and then return the data - only we will have to be 00586 // careful about what Irql we are to make sure the memory mgmt 00587 // stuff will all work 00588 // 00589 00590 if( !AddressSpace ){ 00591 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00592 goto SendReadIoSpaceResponse; 00593 } 00594 00595 // 00596 // Do the IO space read using the appropriate HAL routines based upon 00597 // the default address space (io) and the data size requested. 00598 // 00599 00600 switch( DataSize ){ 00601 00602 case 1: 00603 a->DataValue = READ_PORT_UCHAR( (PUCHAR)(ULONG_PTR) TranslatedAddress.QuadPart ); 00604 break; 00605 00606 case 2: 00607 a->DataValue = READ_PORT_USHORT( (PUSHORT)(ULONG_PTR) TranslatedAddress.QuadPart ); 00608 break; 00609 00610 case 4: 00611 a->DataValue = READ_PORT_ULONG((PULONG)(ULONG_PTR) TranslatedAddress.QuadPart ); 00612 break; 00613 00614 default: 00615 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00616 } 00617 00618 00619 SendReadIoSpaceResponse: 00620 00621 KdpSendPacket( 00622 PACKET_TYPE_KD_STATE_MANIPULATE, 00623 &MessageHeader, 00624 NULL 00625 ); 00626 } 00627 00628 VOID 00629 KdpReadIoSpaceExtended ( 00630 IN PDBGKD_MANIPULATE_STATE64 m, 00631 IN PSTRING AdditionalData, 00632 IN PCONTEXT Context 00633 ) 00634 00635 /*++ 00636 00637 Routine Description: 00638 00639 This function is called in response of a read io space extended state 00640 manipulation message. Its function is to read system io 00641 locations. 00642 00643 Arguments: 00644 00645 m - Supplies the state manipulation message. 00646 00647 AdditionalData - Supplies any additional data for the message. 00648 00649 Context - Supplies the current context. 00650 00651 Return Value: 00652 00653 None. 00654 00655 --*/ 00656 00657 { 00658 PDBGKD_READ_WRITE_IO_EXTENDED64 a = &m->u.ReadWriteIoExtended; 00659 ULONG Length; 00660 STRING MessageHeader; 00661 PUCHAR b; 00662 PUSHORT s; 00663 PULONG l; 00664 ULONG BusNumber; 00665 ULONG AddressSpace; 00666 ULONG SavedAddressSpace; 00667 PHYSICAL_ADDRESS IoAddress; 00668 ULONG DataSize; 00669 PHYSICAL_ADDRESS TranslatedAddress; 00670 INTERFACE_TYPE InterfaceType; 00671 00672 MessageHeader.Length = sizeof(*m); 00673 MessageHeader.Buffer = (PCHAR)m; 00674 00675 ASSERT(AdditionalData->Length == 0); 00676 00677 m->ReturnStatus = STATUS_SUCCESS; 00678 00679 InterfaceType = a->InterfaceType; 00680 BusNumber = a->BusNumber; 00681 AddressSpace = SavedAddressSpace = a->AddressSpace; 00682 IoAddress.QuadPart = (ULONG_PTR)a->IoAddress; 00683 DataSize = a->DataSize; 00684 00685 // 00686 // Zero the return data value. 00687 // 00688 00689 a->DataValue = 0; 00690 00691 // 00692 // Translate the bus address to the physical system address 00693 // or QVA. 00694 // 00695 00696 if( !HalTranslateBusAddress( InterfaceType, 00697 BusNumber, 00698 IoAddress, 00699 &AddressSpace, 00700 &TranslatedAddress ) ){ 00701 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00702 goto SendReadIoSpaceExtendedResponse; 00703 } 00704 00705 // 00706 // N.B. - for the moment we will only support QVAs ie. when AddressSpace 00707 // is one. It may be in later systems that we will have to 00708 // check the address space, map it, perform the virtual read 00709 // unmap, and then return the data - only we will have to be 00710 // careful about what Irql we are to make sure the memory mgmt 00711 // stuff will all work 00712 // 00713 00714 if( !AddressSpace ){ 00715 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00716 goto SendReadIoSpaceExtendedResponse; 00717 } 00718 00719 // 00720 // Do the IO space read using the appropriate HAL routines based upon 00721 // the original address space and the data size requested. 00722 // 00723 00724 if( !SavedAddressSpace ){ 00725 00726 // 00727 // Memory (buffer) space on the bus 00728 // 00729 00730 switch( DataSize ){ 00731 00732 case 1: 00733 a->DataValue = READ_REGISTER_UCHAR( (PUCHAR)(ULONG_PTR) TranslatedAddress.QuadPart ); 00734 break; 00735 00736 case 2: 00737 a->DataValue = READ_REGISTER_USHORT((PUSHORT)(ULONG_PTR) TranslatedAddress.QuadPart ); 00738 break; 00739 00740 case 4: 00741 a->DataValue = READ_REGISTER_ULONG((PULONG)(ULONG_PTR) TranslatedAddress.QuadPart ); 00742 break; 00743 00744 default: 00745 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00746 } 00747 00748 } else { 00749 00750 // 00751 // I/O space on the bus 00752 // 00753 00754 switch( DataSize ){ 00755 00756 case 1: 00757 a->DataValue = READ_PORT_UCHAR( (PUCHAR)(ULONG_PTR) TranslatedAddress.QuadPart ); 00758 break; 00759 00760 case 2: 00761 a->DataValue = READ_PORT_USHORT( (PUSHORT)(ULONG_PTR) TranslatedAddress.QuadPart ); 00762 break; 00763 00764 case 4: 00765 a->DataValue = READ_PORT_ULONG( (PULONG)(ULONG_PTR) TranslatedAddress.QuadPart ); 00766 break; 00767 00768 default: 00769 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00770 } 00771 } 00772 00773 00774 00775 SendReadIoSpaceExtendedResponse: 00776 00777 KdpSendPacket( 00778 PACKET_TYPE_KD_STATE_MANIPULATE, 00779 &MessageHeader, 00780 NULL 00781 ); 00782 } 00783 00784 VOID 00785 KdpWriteIoSpace ( 00786 IN PDBGKD_MANIPULATE_STATE64 m, 00787 IN PSTRING AdditionalData, 00788 IN PCONTEXT Context 00789 ) 00790 00791 /*++ 00792 00793 Routine Description: 00794 00795 This function is called in response of a read io space state 00796 manipulation message. Its function is to read system io 00797 locations. 00798 00799 Arguments: 00800 00801 m - Supplies the state manipulation message. 00802 00803 AdditionalData - Supplies any additional data for the message. 00804 00805 Context - Supplies the current context. 00806 00807 Return Value: 00808 00809 None. 00810 00811 --*/ 00812 00813 { 00814 PDBGKD_READ_WRITE_IO64 a = &m->u.ReadWriteIo; 00815 STRING MessageHeader; 00816 INTERFACE_TYPE InterfaceType; 00817 ULONG BusNumber; 00818 PHYSICAL_ADDRESS IoAddress; 00819 PHYSICAL_ADDRESS TranslatedAddress; 00820 ULONG AddressSpace; 00821 ULONG DataSize; 00822 ULONG Value; 00823 00824 MessageHeader.Length = sizeof(*m); 00825 MessageHeader.Buffer = (PCHAR)m; 00826 00827 ASSERT(AdditionalData->Length == 0); 00828 00829 m->ReturnStatus = STATUS_SUCCESS; 00830 00831 // 00832 // Capture the input parameters and use the default values for those 00833 // parameters not specified in the Api. 00834 // 00835 00836 InterfaceType = Isa; 00837 BusNumber = 0; 00838 AddressSpace = 1; 00839 IoAddress.QuadPart = (ULONG_PTR)a->IoAddress; 00840 DataSize = a->DataSize; 00841 Value = a->DataValue; 00842 00843 // 00844 // Translate the bus address to the physical system address 00845 // or QVA. 00846 // 00847 00848 if( !HalTranslateBusAddress( InterfaceType, 00849 BusNumber, 00850 IoAddress, 00851 &AddressSpace, 00852 &TranslatedAddress ) ){ 00853 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00854 goto SendWriteIoSpaceResponse; 00855 } 00856 00857 // 00858 // N.B. - for the moment we will only support QVAs ie. when AddressSpace 00859 // is one. It may be in later systems that we will have to 00860 // check the address space, map it, perform the virtual read 00861 // unmap, and then return the data - only we will have to be 00862 // careful about what Irql we are to make sure the memory mgmt 00863 // stuff will all work 00864 // 00865 00866 if( !AddressSpace ){ 00867 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00868 goto SendWriteIoSpaceResponse; 00869 } 00870 00871 // 00872 // Do the IO space read using the appropriate HAL routines based upon 00873 // the default address space (io) and the data size requested. 00874 // 00875 00876 switch( DataSize ){ 00877 00878 case 1: 00879 WRITE_PORT_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value ); 00880 break; 00881 00882 case 2: 00883 WRITE_PORT_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value ); 00884 break; 00885 00886 case 4: 00887 WRITE_PORT_ULONG( (PULONG)TranslatedAddress.QuadPart, Value ); 00888 break; 00889 00890 default: 00891 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00892 } 00893 00894 00895 SendWriteIoSpaceResponse: 00896 00897 KdpSendPacket( 00898 PACKET_TYPE_KD_STATE_MANIPULATE, 00899 &MessageHeader, 00900 NULL 00901 ); 00902 } 00903 00904 VOID 00905 KdpWriteIoSpaceExtended ( 00906 IN PDBGKD_MANIPULATE_STATE64 m, 00907 IN PSTRING AdditionalData, 00908 IN PCONTEXT Context 00909 ) 00910 00911 /*++ 00912 00913 Routine Description: 00914 00915 This function is called in response of a read io space extended state 00916 manipulation message. Its function is to read system io 00917 locations. 00918 00919 Arguments: 00920 00921 m - Supplies the state manipulation message. 00922 00923 AdditionalData - Supplies any additional data for the message. 00924 00925 Context - Supplies the current context. 00926 00927 Return Value: 00928 00929 None. 00930 00931 --*/ 00932 00933 { 00934 PDBGKD_READ_WRITE_IO_EXTENDED64 a = &m->u.ReadWriteIoExtended; 00935 ULONG Length; 00936 STRING MessageHeader; 00937 PUCHAR b; 00938 PUSHORT s; 00939 PULONG l; 00940 ULONG BusNumber; 00941 ULONG AddressSpace; 00942 ULONG SavedAddressSpace; 00943 PHYSICAL_ADDRESS IoAddress; 00944 ULONG DataSize; 00945 PHYSICAL_ADDRESS TranslatedAddress; 00946 INTERFACE_TYPE InterfaceType; 00947 ULONG Value; 00948 00949 MessageHeader.Length = sizeof(*m); 00950 MessageHeader.Buffer = (PCHAR)m; 00951 00952 ASSERT(AdditionalData->Length == 0); 00953 00954 m->ReturnStatus = STATUS_SUCCESS; 00955 00956 InterfaceType = a->InterfaceType; 00957 BusNumber = a->BusNumber; 00958 AddressSpace = SavedAddressSpace = a->AddressSpace; 00959 IoAddress.QuadPart = (ULONG_PTR)a->IoAddress; 00960 DataSize = a->DataSize; 00961 Value = a->DataValue; 00962 00963 // 00964 // Translate the bus address to the physical system address 00965 // or QVA. 00966 // 00967 00968 if( !HalTranslateBusAddress( InterfaceType, 00969 BusNumber, 00970 IoAddress, 00971 &AddressSpace, 00972 &TranslatedAddress ) ){ 00973 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00974 goto SendWriteIoSpaceExtendedResponse; 00975 } 00976 00977 // 00978 // N.B. - for the moment we will only support QVAs ie. when AddressSpace 00979 // is one. It may be in later systems that we will have to 00980 // check the address space, map it, perform the virtual read 00981 // unmap, and then return the data - only we will have to be 00982 // careful about what Irql we are to make sure the memory mgmt 00983 // stuff will all work 00984 // 00985 00986 if( !AddressSpace ){ 00987 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00988 goto SendWriteIoSpaceExtendedResponse; 00989 } 00990 00991 // 00992 // Do the IO space read using the appropriate HAL routines based upon 00993 // the original address space and the data size requested. 00994 // 00995 00996 if( !SavedAddressSpace ){ 00997 00998 // 00999 // Memory (buffer) space on the bus 01000 // 01001 01002 switch( DataSize ){ 01003 01004 case 1: 01005 WRITE_REGISTER_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value ); 01006 break; 01007 01008 case 2: 01009 WRITE_REGISTER_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value ); 01010 break; 01011 01012 case 4: 01013 WRITE_REGISTER_ULONG( (PULONG)TranslatedAddress.QuadPart, Value ); 01014 break; 01015 01016 default: 01017 m->ReturnStatus = STATUS_INVALID_PARAMETER; 01018 } 01019 01020 } else { 01021 01022 // 01023 // I/O space on the bus 01024 // 01025 01026 switch( DataSize ){ 01027 01028 case 1: 01029 WRITE_PORT_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value ); 01030 break; 01031 01032 case 2: 01033 WRITE_PORT_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value); 01034 break; 01035 01036 case 4: 01037 WRITE_PORT_ULONG( (PULONG)TranslatedAddress.QuadPart, Value ); 01038 break; 01039 01040 default: 01041 m->ReturnStatus = STATUS_INVALID_PARAMETER; 01042 } 01043 } 01044 01045 01046 01047 SendWriteIoSpaceExtendedResponse: 01048 01049 KdpSendPacket( 01050 PACKET_TYPE_KD_STATE_MANIPULATE, 01051 &MessageHeader, 01052 NULL 01053 ); 01054 } 01055 01056 VOID 01057 KdpGetBusData ( 01058 IN PDBGKD_MANIPULATE_STATE64 m, 01059 IN PSTRING AdditionalData, 01060 IN PCONTEXT Context 01061 ) 01062 01063 /*++ 01064 01065 Routine Description: 01066 01067 This function is called in response to a get bus data state 01068 manipulation message. Its function is to read I/O configuration 01069 space. 01070 01071 Arguments: 01072 01073 m - Supplies the state manipulation message. 01074 01075 AdditionalData - Supplies any additional data for the message. 01076 01077 Context - Supplies the current context. 01078 01079 Return Value: 01080 01081 None. 01082 01083 --*/ 01084 01085 { 01086 PDBGKD_GET_SET_BUS_DATA a = &m->u.GetSetBusData; 01087 ULONG Length; 01088 STRING MessageHeader; 01089 01090 MessageHeader.Length = sizeof(*m); 01091 MessageHeader.Buffer = (PCHAR)m; 01092 01093 ASSERT(AdditionalData->Length == 0); 01094 01095 m->ReturnStatus = STATUS_SUCCESS; 01096 01097 // 01098 // Trim length to fit in a single message 01099 // 01100 01101 if (a->Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) { 01102 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); 01103 } else { 01104 Length = a->Length; 01105 } 01106 01107 // 01108 // Get the bus data. 01109 // 01110 01111 Length = HalGetBusDataByOffset( 01112 a->BusDataType, 01113 a->BusNumber, 01114 a->SlotNumber, 01115 AdditionalData->Buffer, 01116 a->Offset, 01117 Length 01118 ); 01119 01120 // 01121 // Update the data length. 01122 // 01123 01124 a->Length = Length; 01125 01126 AdditionalData->Length = (USHORT)Length; 01127 01128 KdpSendPacket( 01129 PACKET_TYPE_KD_STATE_MANIPULATE, 01130 &MessageHeader, 01131 AdditionalData 01132 ); 01133 } 01134 01135 VOID 01136 KdpSetBusData ( 01137 IN PDBGKD_MANIPULATE_STATE64 m, 01138 IN PSTRING AdditionalData, 01139 IN PCONTEXT Context 01140 ) 01141 01142 /*++ 01143 01144 Routine Description: 01145 01146 This function is called in response to a set bus data state 01147 manipulation message. Its function is to write I/O configuration 01148 space. 01149 01150 Arguments: 01151 01152 m - Supplies the state manipulation message. 01153 01154 AdditionalData - Supplies any additional data for the message. 01155 01156 Context - Supplies the current context. 01157 01158 Return Value: 01159 01160 None. 01161 01162 --*/ 01163 01164 { 01165 PDBGKD_GET_SET_BUS_DATA a = &m->u.GetSetBusData; 01166 ULONG Length; 01167 STRING MessageHeader; 01168 01169 MessageHeader.Length = sizeof(*m); 01170 MessageHeader.Buffer = (PCHAR)m; 01171 01172 m->ReturnStatus = STATUS_SUCCESS; 01173 01174 // 01175 // Get the bus data. 01176 // 01177 01178 Length = HalSetBusDataByOffset( 01179 a->BusDataType, 01180 a->BusNumber, 01181 a->SlotNumber, 01182 AdditionalData->Buffer, 01183 a->Offset, 01184 a->Length 01185 ); 01186 01187 // 01188 // Update the data length. 01189 // 01190 01191 a->Length = Length; 01192 01193 KdpSendPacket( 01194 PACKET_TYPE_KD_STATE_MANIPULATE, 01195 &MessageHeader, 01196 NULL 01197 ); 01198 }

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