> On Apr 15, 2021, at 6:03 PM, Michael Brown wrote: > > On 16/04/2021 01:59, Ethin Probst wrote: >> Also, I'm a bit confused. I've looked at several VirtIO devices now >> and have seen things like this: >> #define VIRTIO_PCI_DEVICE_SIGNATURE SIGNATURE_32 ('V', 'P', 'C', 'I') >> // ... >> UINT32 Signature; >> I'm quite confused because I can't seem to find this anywhere in the >> VirtIO specification. The spec says nothing about signature values >> anywhere, just the magic value of 0x74726976. So where does this come >> from? > > From a quick look at the code, it seems to be a private signature value applied to a software-only data structure used by the UEFI driver, and is used solely for sanity checking that a pointer is pointing to the right kind of object. > Ethin, This is a common edk2 code pattern. We have something called a Containment Record (CR) macro [1] and the DEBUG version of the CR macro [2] checks the signature. What happens is the public API is a Field in the private data structure, thus you can convert the This pointer to the private context of the driver for that protocol instances. The driver publishes the protocol from the Start() function so that is why the This pointer is always going to be a member of the larger private context structure. This pattern is also used for double linked lists as the data structure to represent the link list is generic and the data is attached to it via the Containment Record scheme by making that linked list data structure part of the larger data structure. [1] #define BASE_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - OFFSET_OF (TYPE, Field))) [2] #define CR(Record, TYPE, Field, TestSignature) \ (DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ? \ (TYPE *) (_ASSERT (CR has Bad Signature), Record) : \ BASE_CR (Record, TYPE, Field) Thanks, Andrew Fish