How can ACPI link a permanently connected device to an SoC UART?

HexDump
HexDump New Member Posts: 3

I'm looking for some guidance about getting a Windows SerCx2 peripheral driver set up for UART0 on an UP Squared 7000 Pro. I'm running Windows 11 IoT Enterprise LTSC; BIOS is at 2.22.1292.

On the 7000 Pro, the x7425E's UART0 appears to be the one connected to pins 8 and 10 on the 40-pin header. I'm not really looking to use this as a general-purpose COM port like many of the answers I've been finding here and on the Wiki. Rather, I'm using the 7000 Pro to prototype firmware that will eventually run on a custom board that will have one of the SoC UARTs permanently wired to an on-board custom ASIC. That resource will be shared among multiple applications, and the framework of a UMDF2 or KMDF driver is perfectly suited to managing that.

While I have some Windows driver experience, I'm new to both ACPI and SerCx2.

After going into the BIOS CRB Setup > CRB Chipset > PCH-IO Configuration, enabling UART0 in ISH Configuration, and setting the UART0 Controller to "Communication Port (COM)" in SerialIo Configuration, and uninstalling the Intel UART controller driver (iaLPSS2_UART2_ADL_N.sys), I have both Mincomm and PuTTY able to echo characters through COM3 (alias "\?\ACPI#PNP0501#SERIALIOUART0#{86e0d1e0-8089-11d0-9ce4-08003e301f73}"). It looks like the system is well equipped for my development needs.

So, with Microsoft's SerCx2, I think the basic idea will be to change the UART0 Controller to simply "Enabled" and install Intel's UART controller driver, which I believe fulfills the controller part of the SerCx2 architecture, plugging into the SerCx2 framework that provides the API my peripheral driver will use.

As I understand it, I need to add a Device object in ACPI to represent the custom ASIC, and the hardware ID I declare there (_HID) is what I'll place in my driver's INF file to get it loaded when Windows starts.

The part eluding me at the moment is how to write my Device object's ASL to link the appropriate object representing UART0. The custom ASIC should look to Windows like a fixed non-PnP device attached through a UartSerialBus, I think.

Which object do I need to link to (\\_SB.PC00.UA00, maybe?) and what and how do I express this connection in ASL?

Answers

  • HarryChiu
    HarryChiu New Member Posts: 169 ✭✭✭
  • HexDump
    HexDump New Member Posts: 3
    edited December 13

    Thank you, @HarryChiu . I've made progress, but I'm still not certain \\_SB.PC00.UA00 is the object I should be referencing in my ACPI to make the driver work on the UP Squared.

    I did see that page before and it informed much of what I was doing, and I have been able to get my driver loading, at least. One big piece I needed to dig for was the connection in ACPI between the device on the serial bus, and the serial bus as declared in the resource hub proxy object. For the benefit of others, what I ended up with is ACPI something like this:

    DefinitionBlock ("ACPITABL.dat", "SSDT", 1, "MSFT", "BLIP", 1)
    {
        External (_SB.PC00, DeviceObj)
    
        Scope(\_SB)
        {
    
            Device(RHPX)        // Resource Hub Proxy object
            {
                Name(_HID, "MSFT8000")
                Name(_CID, "MSFT8000")
                Name(_UID, 1)
    
                // Resource at index 0 is UART0. If multiple resources are added to
                // this resource hub proxy object, they'll each be at an index one
                // higher than the one before. If the index of UART0 changes because
                // of new resources added here, be sure to update the index in the
                // BLIP device's UartSerialBus resource to reflect the new index of
                // UART0, or the system will think it is connected somewhere else.
                Name(_CRS, ResourceTemplate()
                {
                    // Define the UART bus
                    UartSerialBus(
                        115200,             // Baud
                        DataBitsEight, 
                        StopBitsOne, 
                        0x00,               // UART handshaking lines used: none.
                        LittleEndian,
                        ParityTypeNone,
                        FlowControlNone, 
                        64,                 // Receive buffer size
                        64,                 // Transmit buffer size
                        "\\_SB.PC00.UA00",  // UART0 on the Intel x7425E
                        ,,,
                    )
                })
            }
    
            Device(BLIP)        // Our custom ASIC device object
            {
                Name(_HID, "BLIP0001")      // BLIP device hardware ID
                Name(_CID, "BLIP0001")      // Compatible ID
                Name(_UID, 1)               // Unique ID
                Name(_CRS, ResourceTemplate()
                {
                    // Define the dependency on the resource hub
                    UartSerialBus(
                        115200,             // Baud
                        DataBitsEight, 
                        StopBitsOne, 
                        0x00,               // UART handshaking lines used: none.
                        LittleEndian,
                        ParityTypeNone,
                        FlowControlNone, 
                        64,                 // Receive buffer size
                        64,                 // Transmit buffer size
                        "\\_SB.RHPX",       // Resource hub proxy (RSPX) object
                        0,                  // Index of UART0 resource in the RHPX object
                        ,,
                    )
                })
            }
    
        }
    }
    

    This is wrapped in a DefinitionBlock so that when compiled into AML it'll produce a file named ACPITABL.dat; when the system is put in test mode (via bcdedit /set TESTSIGNING ON), this file can simply be copied into \Windows\System32 so that it is appended to ACPI's SSDT.

    This results in the Resource Hub Proxy showing up under System Devices in Device Manager. My UMDF2 driver's INF file matches on the device name of BLIP0001, gets loaded by Windows, and also shows up in Device Manager.

    Inside the driver, I followed Microsoft's example for KMDF drivers for getting a connection ID (because that's closer to UMDF2 than their UMDF example), and the code was successfully coming up with a device name of \\.\RESOURCE_HUB\0000000000000002, which I then use in a call to WdfIoTargetCreate() to create a WDFIOTARGET.

    That's about as far as I've gotten, though. Once I have the WDFIOTARGET I use it in a call to WdfIoTargetOpen(). Unfortunately, that consistently returns a status of 0x80070015, "device not ready."

    That's odd.

    I don't know what the issue is, here, yet. Was \\_SB.PC00.UA00 the correct node to reference in my ACPI for the resource hub proxy object?

  • HexDump
    HexDump New Member Posts: 3
    edited December 13

    @HarryChiu : I've also tried referencing \\_SB.UAH0 instead of \\_SB.PC00\UA00 in my ACPI resource hub proxy device object. This causes my driver to not start because it is waiting on the resource hub proxy, which is failing to start with code 12, "This device cannot find enough free resources that it can use. If you want to use this device, you will need to disable one of the other devices on this system."

    That seems a bit goofy. I had UART1 enabled, though (which shows up in Device Manager as "Intel(R) Serial IO UART Host Controller - 54A9"), so I disabled that and rebooted. No use; the resource hub proxy still fails to start with the same message.

    Is there any commented or documented ASL for the UP Squared Pro 7000's ACPI? It's difficult deciphering how things fit together when dealing with 4-character identifiers, at least as a newcomer to ACPI. Some source would make the computer more useful as a reference development platform.

Privacy Policy