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/


GPIO controller driver with PMIO registers

Marshall_CaiMarshall_Cai Member Posts: 234

Hi All,

I am developing a WDF GPIO controller driver for our own ACPI GPIO. However, the ACPI document about the GPIO pins are all marked as PMIO instead of MMIO.

Our Linux team uses inb/outb to read/write the registers. I am wondering how the WDF GPIO controller driver read/write such registers.

From the sample code, the GPIO controller driver would read/write GPIO registers in the way CmResourceTypeMemory and CmResourceTypeCollection. In my case, I think CmResourceTypeCollection would be returned by calling WdfCmResourceListGetDescriptor. Do I need to call READ_PORT_*** API to read the registers?

Thanks,
Marshall

Comments

  • Shane_CorbinShane_Corbin Member Posts: 307

    You should be able to do something like this:

       // Walk through the resource list and store each GPIO in `pDevExt->ConnectionIds`.
       resource_count = WdfCmResourceListGetCount(ResourcesTranslated);
       for (index = 0; index < resource_count; ++index)
       {
          descriptor = WdfCmResourceListGetDescriptor(ResourcesTranslated, index);
          switch (descriptor->Type) 
          {
             // This memory resource supplies the base of the device registers.
             case CmResourceTypeConnection:
                //  Check against expected connection type
                if ((descriptor->u.Connection.Class ==
                   CM_RESOURCE_CONNECTION_CLASS_GPIO) &&
                   (descriptor->u.Connection.Type ==
                      CM_RESOURCE_CONNECTION_TYPE_GPIO_IO)) 
                {
                   pDevExt->ConnectionIds[io_resource_index].LowPart =
                      descriptor->u.Connection.IdLowPart;
                   pDevExt->ConnectionIds[io_resource_index].HighPart =
                      descriptor->u.Connection.IdHighPart;
                }
               break;
             default:
               break;
         }
      }
    

    Then when you want to read/write from one you'll need to find the RESOURCE_HUB request string for the GPIO by doing something like:

       // Find the RESOURCE_HUB request string for this GPIO pin
       RtlInitEmptyUnicodeString(&resource_string,
          resource_string_buffer,
          sizeof(resource_string_buffer));
    
       status = RESOURCE_HUB_CREATE_PATH_FROM_ID(
          &resource_string,
          pDevExt->ConnectionIds[pin_number].LowPart,
          pDevExt->ConnectionIds[pin_number].HighPart);
    

    Once you have the request string you'll have to open the IoTarget by name with WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME.
    From there you can use WdfIoTargetFormatRequestForIoctl with the IOCTL_GPIO_READ_PINS/IOCTL_GPIO_WRITE_PINS ioctls do the equivalent of your Linux teams inb/outb IO.
    Once you've formated the request you can use WdfRequestSend to send it.

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,718

    It is difficult for me to believe that any modern product is still using the x86 I/O ports. How do you even handle that on an ARM system that doesn't have the special instructions?

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

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

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!
Kernel Debugging 13-17 May 2024 Live, Online
Developing Minifilters 1-5 Apr 2024 Live, Online
Internals & Software Drivers 11-15 Mar 2024 Live, Online
Writing WDF Drivers 26 Feb - 1 Mar 2024 Live, Online