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_CHANGE 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                            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(WaitStateChange->ProgramCounter, End) != FALSE) {
    00081         KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0],
    00082                       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_CHANGE 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 = (PVOID)KdpGetCurrentThread();
    00142     WaitStateChange->ProgramCounter = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord);
    00143     KdpQuickMoveMemory((PCHAR)&WaitStateChange->u.Exception.ExceptionRecord,
    00144                        (PCHAR)ExceptionRecord,
    00145                        sizeof(EXCEPTION_RECORD));
    00146
    00147     WaitStateChange->u.Exception.FirstChance = !SecondChance;
    00148
    00149     //
    00150     // Copy the immediate instruction stream into the control report structure.
    00151     //
    00152
    00153     Count =  KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0],
    00154                            WaitStateChange->ProgramCounter,
    00155                            DBGKD_MAXSTREAM);
    00156
    00157     WaitStateChange->ControlReport.InstructionCount = (USHORT)Count;
    00158
    00159     //
    00160     // Clear breakpoints in the copied instruction stream. If any breakpoints
    00161     // are clear, then recopy the instruction strasm.
    00162     //
    00163
    00164     End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1);
    00165     if (KdpDeleteBreakpointRange(WaitStateChange->ProgramCounter, End) != FALSE) {
    00166         KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0],
    00167                       WaitStateChange->ProgramCounter,
    00168                       Count);
    00169     }
    00170
    00171     //
    00172     // Copy the context record into the wait state structure.
    00173     //
    00174
    00175     KdpMoveMemory((PCHAR)&WaitStateChange->Context,
    00176                   (PCHAR)ContextRecord,
    00177                   sizeof(*ContextRecord));
    00178
    00179     return;
    00180 }
    00181
    00182 VOID
    00183 KdpGetStateChange (
    00184     IN PDBGKD_MANIPULATE_STATE ManipulateState,
    00185     IN PCONTEXT ContextRecord
    00186     )
    00187
    00188 /*++
    00189
    00190 Routine Description:
    00191
    00192     Extract continuation control data from Manipulate_State message
    00193
    00194     N.B. This is a noop for MIPS.
    00195
    00196 Arguments:
    00197
    00198     ManipulateState - supplies pointer to Manipulate_State packet
    00199
    00200     ContextRecord - Supplies a pointer to a context record.
    00201
    00202 Return Value:
    00203
    00204     None.
    00205
    00206 --*/
    00207
    00208 {
    00209 }
    00210
    00211 VOID
    00212 KdpReadControlSpace (
    00213     IN PDBGKD_MANIPULATE_STATE m,
    00214     IN PSTRING AdditionalData,
    00215     IN PCONTEXT Context
    00216     )
    00217
    00218 /*++
    00219
    00220 Routine Description:
    00221
    00222     This function is called in response of a read control space state
    00223     manipulation message.  Its function is to read implementation
    00224     specific system data.
    00225
    00226 Arguments:
    00227
    00228     m - Supplies the state manipulation message.
    00229
    00230     AdditionalData - Supplies any additional data for the message.
    00231
    00232     Context - Supplies the current context.
    00233
    00234 Return Value:
    00235
    00236     None.
    00237
    00238 --*/
    00239
    00240 {
    00241
    00242     PDBGKD_READ_MEMORY a = &m->u.ReadMemory;
    00243     ULONG Length;
    00244     STRING MessageHeader;
    00245     PVOID Buffer = AdditionalData->Buffer;
    00246
    00247     MessageHeader.Length = sizeof(*m);
    00248     MessageHeader.Buffer = (PCHAR)m;
    00249
    00250     ASSERT(AdditionalData->Length == 0);
    00251
    00252     if (a->TransferCount > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE))) {
    00253         Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE);
    00254     } else {
    00255         Length = a->TransferCount;
    00256     }
    00257
    00258     ASSERT(sizeof(PVOID) == sizeof(ULONG));
    00259
    00260 //NOTENOTE
    00261 //  This code will in fact only work on a uni-processor as the
    00262 //  m->Processor field is ignored for now
    00263
    00264     //
    00265     // Case on address to determine what part of Control
    00266     // space is being read
    00267     //
    00268
    00269     switch( (ULONG_PTR)a->TargetBaseAddress ){
    00270
    00271         //
    00272         // Return the pcr address for the current processor.
    00273         //
    00274
    00275     case DEBUG_CONTROL_SPACE_PCR:
    00276
    00277         *(PKPCR *)Buffer = KdpGetPcr();
    00278         AdditionalData->Length = sizeof( PKPCR );
    00279         a->ActualBytesRead = AdditionalData->Length;
    00280         m->ReturnStatus = STATUS_SUCCESS;
    00281         break;
    00282
    00283         //
    00284         // Return the prcb address for the current processor.
    00285         //
    00286
    00287     case DEBUG_CONTROL_SPACE_PRCB:
    00288
    00289         *(PKPRCB *)Buffer = KdpGetCurrentPrcb();
    00290         AdditionalData->Length = sizeof( PKPRCB );
    00291         a->ActualBytesRead = AdditionalData->Length;
    00292         m->ReturnStatus = STATUS_SUCCESS;
    00293         break;
    00294
    00295         //
    00296         // Return the pointer to the current thread address for the
    00297         // current processor.
    00298         //
    00299
    00300     case DEBUG_CONTROL_SPACE_THREAD:
    00301
    00302         *(PKTHREAD *)Buffer = KdpGetCurrentThread();
    00303         AdditionalData->Length = sizeof( PKTHREAD );
    00304         a->ActualBytesRead = AdditionalData->Length;
    00305         m->ReturnStatus = STATUS_SUCCESS;
    00306         break;
    00307
    00308         //
    00309         // Return the current Thread Environment Block pointer for the
    00310         // current thread on the current processor.
    00311         //
    00312
    00313     case DEBUG_CONTROL_SPACE_TEB:
    00314
    00315         *(PVOID *)Buffer = (PVOID)NtCurrentTeb();
    00316         AdditionalData->Length = sizeof( struct _TEB * );
    00317         a->ActualBytesRead = AdditionalData->Length;
    00318         m->ReturnStatus = STATUS_SUCCESS;
    00319         break;
    00320
    00321         //
    00322         // Return the dpc active flag for the current processor.
    00323         //
    00324
    00325     case DEBUG_CONTROL_SPACE_DPCACTIVE:
    00326
    00327         *(BOOLEAN *)Buffer = KeIsExecutingDpc();
    00328         AdditionalData->Length = sizeof( ULONG );
    00329         a->ActualBytesRead = AdditionalData->Length;
    00330         m->ReturnStatus = STATUS_SUCCESS;
    00331         break;
    00332
    00333         //
    00334         // Return the internal processor register state.
    00335         //
    00336         // N.B. - the kernel debugger buffer is expected to be allocated
    00337         //        in the 32-bit superpage
    00338         //
    00339         // N.B. - the size of the internal state cannot exceed the size of
    00340         //        the buffer allocated to the kernel debugger via
    00341         //        KDP_MESSAGE_BUFFER_SIZE
    00342         //
    00343
    00344     case DEBUG_CONTROL_SPACE_IPRSTATE:
    00345
    00346         //
    00347         // Guarantee that Buffer is quadword-aligned, and adjust the
    00348         // size of the available buffer accordingly.
    00349         //
    00350
    00351         Buffer = (PVOID)( ((ULONG_PTR)Buffer + 7) & ~7);
    00352
    00353         Length = (ULONG)((ULONG_PTR)&AdditionalData->Buffer[KDP_MESSAGE_BUFFER_SIZE] -
    00354                  (ULONG_PTR)Buffer);
    00355
    00356         AdditionalData->Length = (USHORT)KdpReadInternalProcessorState(
    00357                                              Buffer,
    00358                                              Length );
    00359
    00360         //
    00361         // Check the returned size, if greater than the buffer size than
    00362         // we didn't have a sufficient buffer.  If zero then the call
    00363         // failed otherwise.
    00364         //
    00365
    00366         if( (AdditionalData->Length > KDP_MESSAGE_BUFFER_SIZE) ||
    00367             (AdditionalData->Length == 0) ){
    00368
    00369             AdditionalData->Length = 0;
    00370             m->ReturnStatus = STATUS_UNSUCCESSFUL;
    00371             a->ActualBytesRead = 0;
    00372
    00373         } else {
    00374
    00375             m->ReturnStatus = STATUS_SUCCESS;
    00376             a->ActualBytesRead = AdditionalData->Length;
    00377
    00378         }
    00379
    00380         break;
    00381
    00382         //
    00383         // Return the internal processor counter values.
    00384         //
    00385         // N.B. - the kernel debugger buffer is expected to be allocated
    00386         //        in the 32-bit superpage
    00387         //
    00388         // N.B. - the size of the counters structure cannot exceed the size of
    00389         //        the buffer allocated to the kernel debugger via
    00390         //        KDP_MESSAGE_BUFFER_SIZE
    00391         //
    00392
    00393     case DEBUG_CONTROL_SPACE_COUNTERS:
    00394
    00395         //
    00396         // Guarantee that Buffer is quadword-aligned, and adjust the
    00397         // size of the available buffer accordingly.
    00398         //
    00399
    00400         Buffer = (PVOID)( ((ULONG_PTR)Buffer + 7) & ~7);
    00401
    00402         Length = (ULONG)((ULONG_PTR)&AdditionalData->Buffer[KDP_MESSAGE_BUFFER_SIZE] -
    00403                  (ULONG_PTR)Buffer);
    00404
    00405         AdditionalData->Length = (USHORT)KdpReadInternalProcessorCounters(
    00406                                              Buffer,
    00407                                              Length );
    00408
    00409         //
    00410         // Check the returned size, if greater than the buffer size than
    00411         // we didn't have a sufficient buffer.  If zero then the call
    00412         // failed otherwise.
    00413         //
    00414
    00415         if( (AdditionalData->Length > KDP_MESSAGE_BUFFER_SIZE) ||
    00416             (AdditionalData->Length == 0) ){
    00417
    00418             AdditionalData->Length = 0;
    00419             m->ReturnStatus = STATUS_UNSUCCESSFUL;
    00420             a->ActualBytesRead = 0;
    00421
    00422         } else {
    00423
    00424             m->ReturnStatus = STATUS_SUCCESS;
    00425             a->ActualBytesRead = AdditionalData->Length;
    00426
    00427         }
    00428
    00429         break;
    00430
    00431         //
    00432         // Uninterpreted Special Space
    00433         //
    00434
    00435     default:
    00436
    00437         AdditionalData->Length = 0;
    00438         m->ReturnStatus = STATUS_UNSUCCESSFUL;
    00439         a->ActualBytesRead = 0;
    00440
    00441     }
    00442
    00443     KdpSendPacket(
    00444         PACKET_TYPE_KD_STATE_MANIPULATE,
    00445         &MessageHeader,
    00446         AdditionalData
    00447         );
    00448 }
    00449
    00450 VOID
    00451 KdpWriteControlSpace (
    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 control space state
    00462     manipulation message.  Its function is to write implementation
    00463     specific system data.
    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_WRITE_MEMORY a = &m->u.WriteMemory;
    00481     ULONG Length;
    00482     STRING MessageHeader;
    00483
    00484     MessageHeader.Length = sizeof(*m);
    00485     MessageHeader.Buffer = (PCHAR)m;
    00486
    00487     AdditionalData->Length = 0;
    00488     m->ReturnStatus = STATUS_UNSUCCESSFUL;
    00489     a->ActualBytesWritten = 0;
    00490
    00491     KdpSendPacket(
    00492         PACKET_TYPE_KD_STATE_MANIPULATE,
    00493         &MessageHeader,
    00494         AdditionalData
    00495         );
    00496 }
    00497
    00498 VOID
    00499 KdpReadIoSpace (
    00500     IN PDBGKD_MANIPULATE_STATE m,
    00501     IN PSTRING AdditionalData,
    00502     IN PCONTEXT Context
    00503     )
    00504
    00505 /*++
    00506
    00507 Routine Description:
    00508
    00509     This function is called in response of a read io space state
    00510     manipulation message.  Its function is to read system io
    00511     locations.
    00512
    00513 Arguments:
    00514
    00515     m - Supplies the state manipulation message.
    00516
    00517     AdditionalData - Supplies any additional data for the message.
    00518
    00519     Context - Supplies the current context.
    00520
    00521 Return Value:
    00522
    00523     None.
    00524
    00525 --*/
    00526
    00527 {
    00528     PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo;
    00529     STRING MessageHeader;
    00530     INTERFACE_TYPE InterfaceType;
    00531     ULONG BusNumber;
    00532     PHYSICAL_ADDRESS IoAddress;
    00533     PHYSICAL_ADDRESS TranslatedAddress;
    00534     ULONG AddressSpace;
    00535     ULONG DataSize;
    00536
    00537     MessageHeader.Length = sizeof(*m);
    00538     MessageHeader.Buffer = (PCHAR)m;
    00539
    00540     ASSERT(AdditionalData->Length == 0);
    00541
    00542     m->ReturnStatus = STATUS_SUCCESS;
    00543
    00544     //
    00545     // Capture the input parameters and use the default values for those
    00546     // parameters not specified in the Api.
    00547     //
    00548
    00549     InterfaceType = Isa;
    00550     BusNumber = 0;
    00551     AddressSpace = 1;
    00552     IoAddress.QuadPart = (ULONG_PTR)a->IoAddress;
    00553     DataSize = a->DataSize;
    00554
    00555     //
    00556     // Zero the return data value.
    00557     //
    00558
    00559     a->DataValue = 0;
    00560
    00561     //
    00562     // Translate the bus address to the physical system address
    00563     // or QVA.
    00564     //
    00565
    00566     if( !HalTranslateBusAddress( InterfaceType,
    00567                                  BusNumber,
    00568                                  IoAddress,
    00569                                  &AddressSpace,
    00570                                  &TranslatedAddress ) ){
    00571         m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00572         goto SendReadIoSpaceResponse;
    00573     }
    00574
    00575     //
    00576     // N.B. - for the moment we will only support QVAs ie. when AddressSpace
    00577     //        is one.  It may be in later systems that we will have to
    00578     //        check the address space, map it, perform the virtual read
    00579     //        unmap, and then return the data - only we will have to be
    00580     //        careful about what Irql we are to make sure the memory mgmt
    00581     //        stuff will all work
    00582     //
    00583
    00584     if( !AddressSpace ){
    00585         m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00586         goto SendReadIoSpaceResponse;
    00587     }
    00588
    00589     //
    00590     // Do the IO space read using the appropriate HAL routines based upon
    00591     // the default address space (io) and the data size requested.
    00592     //
    00593
    00594     switch( DataSize ){
    00595
    00596     case 1:
    00597         a->DataValue = READ_PORT_UCHAR( (PUCHAR)TranslatedAddress.LowPart );
    00598         break;
    00599
    00600     case 2:
    00601         a->DataValue = READ_PORT_USHORT( (PUSHORT)TranslatedAddress.LowPart );
    00602         break;
    00603
    00604     case 4:
    00605         a->DataValue = READ_PORT_ULONG((PULONG)TranslatedAddress.LowPart );
    00606         break;
    00607
    00608     default:
    00609         m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00610     }
    00611
    00612
    00613 SendReadIoSpaceResponse:
    00614
    00615     KdpSendPacket(
    00616         PACKET_TYPE_KD_STATE_MANIPULATE,
    00617         &MessageHeader,
    00618         NULL
    00619         );
    00620 }
    00621
    00622 VOID
    00623 KdpReadIoSpaceExtended (
    00624     IN PDBGKD_MANIPULATE_STATE m,
    00625     IN PSTRING AdditionalData,
    00626     IN PCONTEXT Context
    00627     )
    00628
    00629 /*++
    00630
    00631 Routine Description:
    00632
    00633     This function is called in response of a read io space extended state
    00634     manipulation message.  Its function is to read system io
    00635     locations.
    00636
    00637 Arguments:
    00638
    00639     m - Supplies the state manipulation message.
    00640
    00641     AdditionalData - Supplies any additional data for the message.
    00642
    00643     Context - Supplies the current context.
    00644
    00645 Return Value:
    00646
    00647     None.
    00648
    00649 --*/
    00650
    00651 {
    00652     PDBGKD_READ_WRITE_IO_EXTENDED a = &m->u.ReadWriteIoExtended;
    00653     ULONG Length;
    00654     STRING MessageHeader;
    00655     PUCHAR b;
    00656     PUSHORT s;
    00657     PULONG l;
    00658     ULONG BusNumber;
    00659     ULONG AddressSpace;
    00660     ULONG SavedAddressSpace;
    00661     PHYSICAL_ADDRESS IoAddress;
    00662     ULONG DataSize;
    00663     PHYSICAL_ADDRESS TranslatedAddress;
    00664     INTERFACE_TYPE InterfaceType;
    00665
    00666     MessageHeader.Length = sizeof(*m);
    00667     MessageHeader.Buffer = (PCHAR)m;
    00668
    00669     ASSERT(AdditionalData->Length == 0);
    00670
    00671     m->ReturnStatus = STATUS_SUCCESS;
    00672
    00673     InterfaceType = a->InterfaceType;
    00674     BusNumber = a->BusNumber;
    00675     AddressSpace = SavedAddressSpace = a->AddressSpace;
    00676     IoAddress.QuadPart = (ULONG_PTR)a->IoAddress;
    00677     DataSize = a->DataSize;
    00678
    00679     //
    00680     // Zero the return data value.
    00681     //
    00682
    00683     a->DataValue = 0;
    00684
    00685     //
    00686     // Translate the bus address to the physical system address
    00687     // or QVA.
    00688     //
    00689
    00690     if( !HalTranslateBusAddress( InterfaceType,
    00691                                  BusNumber,
    00692                                  IoAddress,
    00693                                  &AddressSpace,
    00694                                  &TranslatedAddress ) ){
    00695         m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00696         goto SendReadIoSpaceExtendedResponse;
    00697     }
    00698
    00699     //
    00700     // N.B. - for the moment we will only support QVAs ie. when AddressSpace
    00701     //        is one.  It may be in later systems that we will have to
    00702     //        check the address space, map it, perform the virtual read
    00703     //        unmap, and then return the data - only we will have to be
    00704     //        careful about what Irql we are to make sure the memory mgmt
    00705     //        stuff will all work
    00706     //
    00707
    00708     if( !AddressSpace ){
    00709         m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00710         goto SendReadIoSpaceExtendedResponse;
    00711     }
    00712
    00713     //
    00714     // Do the IO space read using the appropriate HAL routines based upon
    00715     // the original address space and the data size requested.
    00716     //
    00717
    00718     if( !SavedAddressSpace ){
    00719
    00720         //
    00721         // Memory (buffer) space on the bus
    00722         //
    00723
    00724         switch( DataSize ){
    00725
    00726         case 1:
    00727             a->DataValue = READ_REGISTER_UCHAR( (PUCHAR)TranslatedAddress.LowPart );
    00728             break;
    00729
    00730         case 2:
    00731             a->DataValue = READ_REGISTER_USHORT((PUSHORT)TranslatedAddress.LowPart );
    00732             break;
    00733
    00734         case 4:
    00735             a->DataValue = READ_REGISTER_ULONG((PULONG)TranslatedAddress.LowPart );
    00736             break;
    00737
    00738         default:
    00739             m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00740         }
    00741
    00742     } else {
    00743
    00744         //
    00745         // I/O space on the bus
    00746         //
    00747
    00748         switch( DataSize ){
    00749
    00750         case 1:
    00751             a->DataValue = READ_PORT_UCHAR( (PUCHAR)TranslatedAddress.LowPart );
    00752             break;
    00753
    00754         case 2:
    00755             a->DataValue = READ_PORT_USHORT( (PUSHORT)TranslatedAddress.LowPart );
    00756             break;
    00757
    00758         case 4:
    00759             a->DataValue = READ_PORT_ULONG( (PULONG)TranslatedAddress.LowPart );
    00760             break;
    00761
    00762         default:
    00763             m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00764         }
    00765     }
    00766
    00767
    00768
    00769 SendReadIoSpaceExtendedResponse:
    00770
    00771     KdpSendPacket(
    00772         PACKET_TYPE_KD_STATE_MANIPULATE,
    00773         &MessageHeader,
    00774         NULL
    00775         );
    00776 }
    00777
    00778 VOID
    00779 KdpWriteIoSpace (
    00780     IN PDBGKD_MANIPULATE_STATE m,
    00781     IN PSTRING AdditionalData,
    00782     IN PCONTEXT Context
    00783     )
    00784
    00785 /*++
    00786
    00787 Routine Description:
    00788
    00789     This function is called in response of a read io space state
    00790     manipulation message.  Its function is to read system io
    00791     locations.
    00792
    00793 Arguments:
    00794
    00795     m - Supplies the state manipulation message.
    00796
    00797     AdditionalData - Supplies any additional data for the message.
    00798
    00799     Context - Supplies the current context.
    00800
    00801 Return Value:
    00802
    00803     None.
    00804
    00805 --*/
    00806
    00807 {
    00808     PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo;
    00809     STRING MessageHeader;
    00810     INTERFACE_TYPE InterfaceType;
    00811     ULONG BusNumber;
    00812     PHYSICAL_ADDRESS IoAddress;
    00813     PHYSICAL_ADDRESS TranslatedAddress;
    00814     ULONG AddressSpace;
    00815     ULONG DataSize;
    00816     ULONG Value;
    00817
    00818     MessageHeader.Length = sizeof(*m);
    00819     MessageHeader.Buffer = (PCHAR)m;
    00820
    00821     ASSERT(AdditionalData->Length == 0);
    00822
    00823     m->ReturnStatus = STATUS_SUCCESS;
    00824
    00825     //
    00826     // Capture the input parameters and use the default values for those
    00827     // parameters not specified in the Api.
    00828     //
    00829
    00830     InterfaceType = Isa;
    00831     BusNumber = 0;
    00832     AddressSpace = 1;
    00833     IoAddress.QuadPart = (ULONG_PTR)a->IoAddress;
    00834     DataSize = a->DataSize;
    00835     Value = a->DataValue;
    00836
    00837     //
    00838     // Translate the bus address to the physical system address
    00839     // or QVA.
    00840     //
    00841
    00842     if( !HalTranslateBusAddress( InterfaceType,
    00843                                  BusNumber,
    00844                                  IoAddress,
    00845                                  &AddressSpace,
    00846                                  &TranslatedAddress ) ){
    00847         m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00848         goto SendWriteIoSpaceResponse;
    00849     }
    00850
    00851     //
    00852     // N.B. - for the moment we will only support QVAs ie. when AddressSpace
    00853     //        is one.  It may be in later systems that we will have to
    00854     //        check the address space, map it, perform the virtual read
    00855     //        unmap, and then return the data - only we will have to be
    00856     //        careful about what Irql we are to make sure the memory mgmt
    00857     //        stuff will all work
    00858     //
    00859
    00860     if( !AddressSpace ){
    00861         m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00862         goto SendWriteIoSpaceResponse;
    00863     }
    00864
    00865     //
    00866     // Do the IO space read using the appropriate HAL routines based upon
    00867     // the default address space (io) and the data size requested.
    00868     //
    00869
    00870     switch( DataSize ){
    00871
    00872     case 1:
    00873         WRITE_PORT_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value );
    00874         break;
    00875
    00876     case 2:
    00877         WRITE_PORT_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value );
    00878         break;
    00879
    00880     case 4:
    00881         WRITE_PORT_ULONG( (PULONG)TranslatedAddress.QuadPart, Value );
    00882         break;
    00883
    00884     default:
    00885         m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00886     }
    00887
    00888
    00889 SendWriteIoSpaceResponse:
    00890
    00891     KdpSendPacket(
    00892         PACKET_TYPE_KD_STATE_MANIPULATE,
    00893         &MessageHeader,
    00894         NULL
    00895         );
    00896 }
    00897
    00898 VOID
    00899 KdpWriteIoSpaceExtended (
    00900     IN PDBGKD_MANIPULATE_STATE m,
    00901     IN PSTRING AdditionalData,
    00902     IN PCONTEXT Context
    00903     )
    00904
    00905 /*++
    00906
    00907 Routine Description:
    00908
    00909     This function is called in response of a read io space extended state
    00910     manipulation message.  Its function is to read system io
    00911     locations.
    00912
    00913 Arguments:
    00914
    00915     m - Supplies the state manipulation message.
    00916
    00917     AdditionalData - Supplies any additional data for the message.
    00918
    00919     Context - Supplies the current context.
    00920
    00921 Return Value:
    00922
    00923     None.
    00924
    00925 --*/
    00926
    00927 {
    00928     PDBGKD_READ_WRITE_IO_EXTENDED a = &m->u.ReadWriteIoExtended;
    00929     ULONG Length;
    00930     STRING MessageHeader;
    00931     PUCHAR b;
    00932     PUSHORT s;
    00933     PULONG l;
    00934     ULONG BusNumber;
    00935     ULONG AddressSpace;
    00936     ULONG SavedAddressSpace;
    00937     PHYSICAL_ADDRESS IoAddress;
    00938     ULONG DataSize;
    00939     PHYSICAL_ADDRESS TranslatedAddress;
    00940     INTERFACE_TYPE InterfaceType;
    00941     ULONG Value;
    00942
    00943     MessageHeader.Length = sizeof(*m);
    00944     MessageHeader.Buffer = (PCHAR)m;
    00945
    00946     ASSERT(AdditionalData->Length == 0);
    00947
    00948     m->ReturnStatus = STATUS_SUCCESS;
    00949
    00950     InterfaceType = a->InterfaceType;
    00951     BusNumber = a->BusNumber;
    00952     AddressSpace = SavedAddressSpace = a->AddressSpace;
    00953     IoAddress.QuadPart = (ULONG_PTR)a->IoAddress;
    00954     DataSize = a->DataSize;
    00955     Value = a->DataValue;
    00956
    00957     //
    00958     // Translate the bus address to the physical system address
    00959     // or QVA.
    00960     //
    00961
    00962     if( !HalTranslateBusAddress( InterfaceType,
    00963                                  BusNumber,
    00964                                  IoAddress,
    00965                                  &AddressSpace,
    00966                                  &TranslatedAddress ) ){
    00967         m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00968         goto SendWriteIoSpaceExtendedResponse;
    00969     }
    00970
    00971     //
    00972     // N.B. - for the moment we will only support QVAs ie. when AddressSpace
    00973     //        is one.  It may be in later systems that we will have to
    00974     //        check the address space, map it, perform the virtual read
    00975     //        unmap, and then return the data - only we will have to be
    00976     //        careful about what Irql we are to make sure the memory mgmt
    00977     //        stuff will all work
    00978     //
    00979
    00980     if( !AddressSpace ){
    00981         m->ReturnStatus = STATUS_INVALID_PARAMETER;
    00982         goto SendWriteIoSpaceExtendedResponse;
    00983     }
    00984
    00985     //
    00986     // Do the IO space read using the appropriate HAL routines based upon
    00987     // the original address space and the data size requested.
    00988     //
    00989
    00990     if( !SavedAddressSpace ){
    00991
    00992         //
    00993         // Memory (buffer) space on the bus
    00994         //
    00995
    00996         switch( DataSize ){
    00997
    00998         case 1:
    00999             WRITE_REGISTER_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value );
    01000             break;
    01001
    01002         case 2:
    01003             WRITE_REGISTER_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value );
    01004             break;
    01005
    01006         case 4:
    01007             WRITE_REGISTER_ULONG( (PULONG)TranslatedAddress.QuadPart, Value );
    01008             break;
    01009
    01010         default:
    01011             m->ReturnStatus = STATUS_INVALID_PARAMETER;
    01012         }
    01013
    01014     } else {
    01015
    01016         //
    01017         // I/O space on the bus
    01018         //
    01019
    01020         switch( DataSize ){
    01021
    01022         case 1:
    01023             WRITE_PORT_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value );
    01024             break;
    01025
    01026         case 2:
    01027             WRITE_PORT_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value);
    01028             break;
    01029
    01030         case 4:
    01031             WRITE_PORT_ULONG( (PULONG)TranslatedAddress.QuadPart, Value );
    01032             break;
    01033
    01034         default:
    01035             m->ReturnStatus = STATUS_INVALID_PARAMETER;
    01036         }
    01037     }
    01038
    01039
    01040
    01041 SendWriteIoSpaceExtendedResponse:
    01042
    01043     KdpSendPacket(
    01044         PACKET_TYPE_KD_STATE_MANIPULATE,
    01045         &MessageHeader,
    01046         NULL
    01047         );
    01048 }