test: kdcpuapi.c Source File

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 }