Hi Ard,
The capsule configuration table entry memory layout here looks like:
For capsule guid xxx: | (u32) capsule number a | (u64) 1st capsule
physical addr | (u64) 2nd capsule physical addr | ... | (u64) a-st capsule
physical addr |
So if I do "capsule += sizeof(*uint32_t);" then the value for each capsule
physical address will be shifted 4 bytes backward.
Do you think the way that we define a '__packed' structure as like below,
map it to the configuration table, and then use it to fetch the capsule number
and each capsule physical address is ok ?
typedef struct {
u32 capsule_array_number;
void *capsule_addr[];
} __packed efi_capsule_table_t;
Thanks!
BR
qiuxu
-----Original Message-----
From: Ard Biesheuvel [mailto:[email protected]]
Sent: Friday, March 3, 2017 12:46 AM
To: Matt Fleming <[email protected]>
Cc: Zhuo, Qiuxu <[email protected]>; [email protected]; Luck, Tony
<[email protected]>
Subject: Re: [PATCH v2 1/2] efi/capsule: Add 'capsule' lookup support
On 2 March 2017 at 16:45, Ard Biesheuvel <[email protected]> wrote:
> On 2 March 2017 at 16:44, Matt Fleming <[email protected]> wrote:
>> On Thu, 02 Mar, at 03:38:51PM, Ard Biesheuvel wrote:
>>>
>>> > + if (!capsule)
>>> > + return -ENOMEM;
>>> > +
>>> > + capsule += sizeof(uint32_t);
>>>
>>> This is incorrect for 64-bit. You need to increment by the size of
>>> unsigned long here, regardless of the size of efi_capsule_num.
>>
>> I'm almost positive this is correct, but I can't find the bit in the
>> spec that says why. We're not trying to step over a pointer here, if
>> memory serves, it's a capsule count or something and uint32_t is the
>> right type.
>>
>
> Yes, but the next struct member is an array of pointers, so you need
> to advance 8 bytes to get to it due to its alignment
From EDK2:
typedef struct {
///
/// the size of the array of capsules.
///
UINT32 CapsuleArrayNumber;
///
/// Point to an array of capsules that contain the same CapsuleGuid value.
///
VOID* CapsulePtr[1];
} EFI_CAPSULE_TABLE;