Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


How to obtain physical memory address in a driver based from AVStream?

JaFojtikJaFojtik Member MODERATED Posts: 4

I has been writing a camera driver. This driver really displays video.

I have run into a a following problem, I have no clue how to get physical address of stream pointer. So I has been allocated my own memory and copy a data twice. First time through DMA and second time by using CPU. This process eats CPU, DMA itself has throughput 6Gbit/s and does not affect CPU.

I has been reading other discussions, but there is not a hint, how to get access to physical memory address.
https://community.osr.com/discussion/220240

There should be a memory model somehow attached to a pin. My device needs 32bit address alignment and can operate in scatter getter mode.

Or is it possible another way to inject preallocated memory to a pin?
Or to assign a memory model to a pin that ensures that proper memory is allocated?
Or another approach???

NTSTATUS CCapturePin::Process()
{
  PAGED_CODE();
  NTSTATUS Status = STATUS_SUCCESS;
  PKSSTREAM_POINTER Leading;
  Leading = KsPinGetLeadingEdgeStreamPointer(m_Pin, KSSTREAM_POINTER_STATE_LOCKED);
  .....
  Status = KsStreamPointerClone(Leading, NULL, sizeof(STREAM_POINTER_CONTEXT), &ClonePointer);
   ULONG MappingsUsed = m_Device->ProgramScatterGatherMappings(m_channel, &(SPContext->BufferVirtual), Leading->OffsetOut.Mappings, Leading->OffsetOut.Remaining);

The function ProgramScatterGatherMappings only breaks already given memory to smaller peaces. The PKSSTREAM_POINTER structure seems to contain something that could discover physical memory.
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ks/ns-ks-_ksstream_pointer
https://docs.microsoft.com/is-is/windows-hardware/drivers/ddi/ks/ns-ks-_ksmapping

Thank you very much for any hint.

Comments

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,692

    I'm not sure how you missed it. If you specify KSPIN_FLAG_GENERATE_MAPPINGS, as the sample AVStream drivers do, then Leading->OffsetOut.Mappings (as mentioned in your code) contains the scatter/gather list. It's chock full of physical addresses.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • JaFojtikJaFojtik Member MODERATED Posts: 4
    edited October 28

    @Tim_Roberts said:
    I'm not sure how you missed it. If you specify KSPIN_FLAG_GENERATE_MAPPINGS, as the sample AVStream drivers do, then Leading->OffsetOut.Mappings (as mentioned in your code) contains the scatter/gather list. It's chock full of physical addresses.

    Thank you very much for your response.

    The SPIN_FLAG_GENERATE_MAPPINGS DOES NOT exist in the latest github version:
    https://github.com/microsoft/Windows-driver-samples/blob/master/avstream/avshws/filter.cpp
    It is present in the older versions of Microsoft's DDKs though. It is easy to overlook already removed code.

    From older DDK:

    const KSPIN_DESCRIPTOR_EX CaptureFilterPinDescriptors [CAPTURE_FILTER_PIN_COUNT] = {
        // Video Capture Pin
        {
            &CapturePinDispatch,
            NULL,             
            {
                0,                              // Interfaces (NULL, 0 == default)
                NULL,
                0,                              // Mediums (NULL, 0 == default)
                NULL,
                SIZEOF_ARRAY(CapturePinDataRanges),// Range Count
                CapturePinDataRanges,           // Ranges
                KSPIN_DATAFLOW_OUT,             // Dataflow
                KSPIN_COMMUNICATION_BOTH,       // Communication
                &PIN_CATEGORY_CAPTURE,          // Category
                &g_PINNAME_VIDEO_CAPTURE,       // Name
                0                               // Reserved
            },
    #ifdef _X86_                                
            KSPIN_FLAG_GENERATE_MAPPINGS |      // Pin Flags
    #endif
            KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY,
            1,                                  // Instances Possible
            1,                                  // Instances Necessary
            &CapturePinAllocatorFraming,        // Allocator Framing
            reinterpret_cast <PFNKSINTERSECTHANDLEREX> 
                (CCapturePin::IntersectHandler)
        }
    };
    

    It seems to me that KSPIN_FLAG_GENERATE_MAPPINGS relates only to 32 bit code and not to 64 bit code. I think that DMA in AVstream is just a fake. Even when I attempt to allow x86 only branches for 64 bit code it stopped to work. There is something highly unclean and Microsoft solved to remove a code instead of fix.

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,692

    It seems to me that KSPIN_FLAG_GENERATE_MAPPINGS relates only to 32 bit code and not to 64 bit code.

    Not true. I don't know why they removed that from the later samples, but as far as I know it works identically on both platforms. The documentation doesn't mention any problems. Did you try remove those silly ifdefs? Do you get mappings when you do that?

    I think that DMA in AVstream is just a fake.

    I'm not sure what you mean by that. The GENERATE_MAPPINGS flag creates a scatter/gather list. That's as real as it gets. Now, all of my recent AVStream work has been with USB devices, so maybe there's some strange corner cases, but the fundamentals should work.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • JaFojtikJaFojtik Member MODERATED Posts: 4
    edited October 29

    @Tim_Roberts said:
    Not true. I don't know why they removed that from the later samples, but as far as I know it works identically on both platforms. The documentation doesn't mention any problems. Did you try remove those silly ifdefs? Do you get mappings when you do that?

    Yes, I did. The AVstream driver stopped to generate video on 64bit arch when these DMA related branches are enabled. I have identified one 64bit issue.
    KsDeviceRegisterAdapterObject is not intended for 64 bit arch
    https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/supporting-dma-in-64-bit-avstream-drivers
    But it still seems to me that there are more issues.

    As I has been written, the DMA traces has been completely removed from official Microsoft's example driver.

    #if defined(_X86_DMA_)
            //
            // DMA operations illustrated in this sample are applicable only for 32bit platform.
            //
           ............
            if(NT_SUCCESS (Status)) {
                // Initialize our DMA adapter object with AVStream. This is 
                // **ONLY** necessary **IF** you are doing DMA directly into
                // capture buffers as this sample does. For this,
                // KSPIN_FLAG_GENERATE_MAPPINGS must be specified on a queue.
    
                // The (1 << 20) below is the maximum size of a single s/g mapping
                // that this hardware can handle. Note that I have pulled this
                // number out of thin air for the "fake" hardware.
    #if !defined(_WIN64)
                KsDeviceRegisterAdapterObject(m_Device, m_DmaAdapterObject, (1<<20), sizeof(KSMAPPING));
    #else   // All drivers compiled for Win64 should use IKsDeviceFunctions::RegisterAdapterObjectEx instead.
    // Register the DMA adapter with AVStream
               IKsDeviceFunctions *DeviceFunctions;
               Status = DeviceUnk->QueryInterface(__uuidof(IKsDeviceFunctions), (PVOID *)&DeviceFunctions);
    
               if(NT_SUCCESS(Status))
               {
                 DeviceFunctions->RegisterAdapterObjectEx(m_DmaAdapterObject, &DeviceDescription, m_Device->Context->NumMapRegisters, (1<<20), sizeof(KSMAPPING));
                 DeviceFunctions->Release();
               }
               else     // If this call fails, call KsDeviceRegisterAdapterObject to
               {        // preserve downlevel load compatibility.
             KsDeviceRegisterAdapterObject(m_Device, m_DmaAdapterObject, (1<<20), sizeof(KSMAPPING));
               }
    #endif
            }
    #endif
    

    Anyway thank you very much for pointing a right way how to make DMA working. I will try to locate and analyse all X86 related branches in AVstream camera example. I has been renamed X86 to X86_DMA to be abble to enable these branches on 64bit arch.

    According to my best, the DMA related code stub in AVstream never worked on 64 bit arch.

    Post edited by JaFojtik on
  • JaFojtikJaFojtik Member MODERATED Posts: 4
    edited October 29

    I has been carefully enabled all DMA related stub branches and driver does not load on Windows 64 with error -10.
    Although DMA stub compilled in works fine on 32 bit platform.

    [MODS: We removed text containing extreme violation of forum rules here]

    Post edited by Peter_Viscarola_(OSR) on
  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,157
    edited October 29

    Mr @JaFojtik : that was a major violation of one of the primary rules of this forum. I’m locking this thread, and warning you one such additional violation will earn you a lifetime ban. I hope that’s clear enough for you. If it’s not... email me (my email is in my profile).

    ETA: I have also placed you on moderation, just in case.

    Nice job, by the way. Violating the rules on your first day here. That’s a record.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

This discussion has been closed.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Writing WDF Drivers 7 Dec 2020 LIVE ONLINE
Internals & Software Drivers 25 Jan 2021 LIVE ONLINE
Developing Minifilters 8 March 2021 LIVE ONLINE