[SeaBIOS] [PATCH 1/2] Add QEMU fw_cfg DMA interface
Stefan Hajnoczi
stefanha at gmail.com
Thu Aug 6 20:29:19 CET 2015
On Thu, Aug 6, 2015 at 5:15 PM, Laszlo Ersek <lersek at redhat.com> wrote:
> On 08/06/15 14:35, Stefan Hajnoczi wrote:
>> On Thu, Aug 6, 2015 at 12:02 PM, Marc Marí <markmb at redhat.com> wrote:
>>> + if (qemu_cfg_dma_enabled()) {
>>> + QemuCfgDmaAccess access;
>>> +
>>> + access.address = (u64)(u32)buf;
>>> + access.length = len;
>>> + access.control = QEMU_CFG_DMA_CTL_READ;
>>> +
>>> + /*
>>> + * The out is done before the write of the variables on memory. This
>>> + * causes misread on the QEMU side.
>>> + */
>>> + barrier();
>>> +
>>> + outl((u32)&access, PORT_QEMU_CFG_DMA_ADDR);
>>
>> I thought PORT_QEMU_CFG_DMA_ADDR is a 64-bit register according to the
>> spec you posted?
>>
>>> + while(access.length != 0 && !(access.control & QEMU_CFG_DMA_CTL_ERROR));
>>
>> Either the field accesses need to be marked volatile, or a barrier is
>> needed to force the compiler to reload these register from memory each
>> iteration of the loop.
>
> Better yet, I would recommend declaring (and here, also defining)
> "access" as "volatile".
>
> volatile QemuCfgDmaAccess access;
>
>> I think the problem is that there are no "sequence points" (according
>> to the C language specification) in this loop, so the compiler may
>> assume that access.length and access.control will not change.
>> https://en.wikipedia.org/wiki/Sequence_point
>
> The loop does contain sequence points; three in total.
>
> Appendix C of the ISO C spec gives an informative summary on the
> sequence points (with references to the individual normative passages).
> Quoting from appendix C:
>
> 1 The following are the sequence points described in 5.1.2.3:
>
> [...]
>
> - The end of the first operand of the following operators: logical
> AND && (6.5.13); [...]
>
> [...]
>
> - The end of a full expression: [...] the expression in an
> expression statement (6.8.3); [...] the controlling expression of
> a while or do statement (6.8.5); [...]
>
> - Here we have the controlling expression of a while statement.
> - In that expression, we also have a logical AND operator.
> - And the null statement in the loop body is an expression statement.
>
> The lack of sequence points is not the problem (we do have sequence
> points). The problem is that without "volatile", the compiler might
> optimize out the accesses, because it deduces that the expressions
> produce no side effects.
>
> 5.1.2.3 Program execution
>
> [...]
>
> 2 Accessing a volatile object, [...] are all side effects, which are
> changes in the state of the execution environment. Evaluation of an
> expression may produce side effects. At certain specified points in
> the execution sequence called sequence points, all side effects of
> previous evaluations shall be complete and no side effects of
> subsequent evaluations shall have taken place. [...]
>
> 3 In the abstract machine, all expressions are evaluated as specified
> by the semantics. An actual implementation need not evaluate part
> of an expression if it can deduce that its value is not used and
> that no needed side effects are produced (including any caused by
> calling a function or accessing a volatile object).
You are right. I misremembered what sequence points mean. Thanks for
the quotes from the standard.
Stefan
More information about the SeaBIOS
mailing list