Search code examples
iodriveremulationuefiefi

Is there any way of emulating an I/O device in UEFI?


Is there any way of emulating an I/O device (eg. super IO controller) in an UEFI runtime driver running behind the OS?


Solution

  • You will need to create an SMM driver that traps specific I/O ranges, generating SMIs, which will route these accesses to your driver. Values written to the trapped I/O ranges can be retrieved from the CPU Save State area by your driver and processed accordingly by your emulated device's state machine. Values that the OS reads from the trapped I/O range will be returned by your driver by replacing the saved state of the EAX register in the CPU Save State, where the value is returned on x86 systems.

    This technique was widely used by legacy BIOSes to emulate 8042 keyboard controller and support USB HID devices at the BIOS level (AKA Legacy USB). Note, that SMM is only available on x86 systems and is very platform-dependent, i.e. your driver may work on one platform, but not the other one. There is a good level of SMM abstraction in modern UEFI implementations, which helps scalability of SMM code, but I/O trapping capabilities vary for different chipsets. SMM-based emulation capabilities were taken to the extreme in AMD Geode processors, where we emulated most of the PC peripherals, not only SuperIOs, but all the way up to audio and video controllers.