Legacy device can't find enough free resources

I’m attempting to develop a KMDF driver for a legacy (non-PNP) ISA device. My test set up is Windows 10 21H2 running on VirtualBox with a custom plugin that simulates the I/O, IRQ and memory of the target hardware.

Despite this being a non-PNP device I believe I should be developing a PNP driver and using the INF file to specify the actual resources to be used. These will then be passed to the driver through the EvtDevicePrepareHardware callback.

I’m using the FactDef section rather than LogConfig because from what I’ve read the LogConfig section is both deprecated and ignored whereas FactDef is only deprecated. The INF section looks like this:

[MyISADrv_Device.NT.FactDef]
ConfigPriority=HARDRECONFIG
IOConfig=1C00-1C03(0FFF::)
IRQConfig=5
;MemConfig=D0000-DFFFF

The driver is installed by using the “Add legacy hardware” option in device manager. I see a call to EvtDriverDeviceAdd followed by a call to EvtDevicePrepareHardware with the specifed resources and everything works as expected.

If I uncomment the MemConfig line then I see the call to EvtDriverDeviceAdd but EvtDevicePrepareHardware is never called and the device is flagged as having a problem:

“This device cannot find enough free resources that it can use. (Code 12)”

After reading this article on hardware resources I added additional callbacks for EvtDeviceFilterRemoveResourceRequirements, EvtDeviceFilterAddResourceRequirements and EvtDeviceRemoveAddedResources. I see calls to the first two functions with the expected resources however the third function is never called.

The article above talks about the resource requests being passed to the bus driver, but I don’t know what bus driver that would be as this is effectively a root-enumerated device.

As far as I can tell there doesn’t appear to be a conflict with any other hardware for the address range D0000-DFFFF so does that mean that Windows thinks that those addresses simply don’t exist and therefore cannot be used?

It may be that this works just fine on the target hardware but that isn’t available for testing just yet so I’d like to understand why it fails in the virtual environment.

So after a LOT of research and experimentation it seems that the answer is ACPI.

I had assumed that because this is a legacy device Windows would just use the resources specified in the INF file without question because it has no way to detect if the device is actually there.

It seems that’s not the case because even though it’s a legacy device it’s still considered a resource consumer in ACPI terms so there has to be an equivalent resource producer to provide the address space that it sits within.

Looking at the source for the DSDT provided with VirtualBox (vbox.dsl) under _SB.PCI0 there is a region that covers the addresses A0000-BFFFF for the VGA memory but nothing for the region D0000-DFFFF that I’m trying to use:

DwordMemory( // descriptor for video RAM behind ISA bus
        ResourceProducer,        // bit 0 of general flags is 0
        PosDecode,
        MinFixed,                // Range is fixed
        MaxFixed,                // Range is Fixed
        Cacheable,
        ReadWrite,
        0x00000000,              // Granularity
        0x000a0000,              // Min
        0x000bffff,              // Max
        0x00000000,              // Translation
        0x00020000               // Range Length
        )

I tried to add a resource producer for the D0000 region by creating an SDST with the following:

DefinitionBlock ("SSDT.aml", "SSDT", 5, "MB", "ISA", 1)
{
    External (_SB.PCI0, DeviceObj)

    Scope (_SB.PCI0)
    {
        Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
        {
            DwordMemory(
                 ResourceProducer,        // bit 0 of general flags is 0
                 PosDecode,
                 MinFixed,                // Range is fixed
                 MaxFixed,                // Range is Fixed
                 Cacheable,
                 ReadWrite,
                 0x00000000,              // Granularity
                 0x000d0000,              // Min
                 0x000dffff,              // Max
                 0x00000000,              // Translation
                 0x00010000               // Range Length
                 )
        })
    }
}

This was compiled and copied to %windir%\system32\acpitabl.dat as described here but unfortunately it didn’t work.

Instead I ended up modifying the DSDT for VirtualBox. This would normally mean re-compiling the whole application which is quite a task in itself so I just patched VBoxDD.dll to extend the top of the VGA memory region from BFFFF to DFFFF. My driver now loads correctly without any problems :smile:

As an interesting side note, in trying to debug this I wrote a WDM driver that essentially does nothing but has an INF file with the same fixed resource requirements. I tried loading this on Windows XP and got the same result except that it was more helpful then Windows 10 by actually telling you which resource is causing the problem and why:

“Memory range 000D0000 - 000DFFFF not available”.

Windows 10 just says:

“No conflicts”.

I hope this followup helps someone if they attempt something similar in the future. I’m interesting to hear anyone’s thoughts on where I went wrong with my SSDT and if this method can be made to work.

1 Like