<html><body><br><blockquote>On Sun, Mar 19, 2017 at 01:50:47PM +0100, petr.berky@email.cz wrote:
<br>> I am working on an issue with SeaBIOS running in Bochs emulator. I found
<br>> I need to revert SeaBIOS patch d449a11, otherwise Bochs freezes. After
<br>> the further investigation, I narrowed down the problem to those lines:
<br>> 
<br>> File: src/fw/shadow.c
<br>> Function: __make_bios_writable_intel
<br>>  48  // Write PAM settings back to pci config space
<br>>  49  pci_config_writel(bdf, ALIGN_DOWN(pam0, 4), pamdata.data32[0]);
<br>>  50  pci_config_writel(bdf, ALIGN_DOWN(pam0, 4) + 4, pamdata.data32[1]);
<br>> 
<br>> File: src/fw/shadow.c
<br>> Function: make_bios_readonly_intel
<br>> 109  // Write PAM settings back to pci config space
<br>> 110  pci_config_writel(bdf, ALIGN_DOWN(pam0, 4), pamdata.data32[0]);
<br>> 111  pci_config_writel(bdf, ALIGN_DOWN(pam0, 4) + 4, pamdata.data32[1]);
<br>> 
<br>> What has changed, comparing to the code before patch d449a11 is the
<br>> order of writes to PAM registers.
<br>> 
<br>> Before d449a11 the order was: 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x59
<br>> After  d449a11 the order is : 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f
<br>> 
<br>> I believe also the 0x58 (DRAMT?) register is written after the patch
<br>> d449a11 and was not before.
<br>> 
<br>> I checked, and the registers values after write are exactly the same
<br>> in both cases (before/after patch). This lead me to think the order
<br>> of writes matters.
<br>> 
<br>> So I prepared the patch that restores the old order. I works well and
<br>> fixes the issue with Bochs. But there is still one think I cannot
<br>> explain and I hope I can find some help here. If you look on the patch
<br>> below, you will see I had to use different pci write functions in
<br>> __make_bios_writable_intel and make_bios_readonly_intel. The only
<br>> difference in those functions (I think) is the size of data that
<br>> is written at one call. Still It does not work for me when written
<br>> some other way. Again, I would appreciate if someone could explain
<br>> it to me or point me some documentation.
<br>
<br>As background, the reason for d449a11 is to improve the startup time
<br>on QEMU.  When the updates to the PAM registers were written one byte
<br>at a time it caused significantly more time for QEMU to make the
<br>memory changes.
<br>
<br>> Just to summarize, I have two questions:
<br>> 
<br>>   1.  Why the order of pci writes makes a difference here?
<br>
<br>To the best of my knowledge, it shouldn't.  It doesn't on QEMU.  It
<br>might be a Bochs bug.  Also, it may not be the ordering that is
<br>causing the problem - Bochs may not like the 4 byte writes.
<br>
<br>>   2.  Why the size of pci writes matters?
<br>
<br>Again, to the best of my knowledge, it shouldn't.
<br>
<br>Can you check if the problem is really due to ordering of writes:
<br>
<br>    for (i=0; i<8; i++)
<br>        pci_config_writeb(bdf, ALIGN_DOWN(pam0, 4) + i, pamdata.data8[i]);
<br>
<br>or just due to the write to 0x58:
<br>
<br>    for (i=0; i<7; i++)
<br>        pci_config_writeb(bdf, pam0 + i, pamdata.data8[(pam0 % 4) + i]);
<br>
<br>or because 4 byte pci config writes are done?
<br>
<br>    for (i=0; i<4; i++)
<br>        pci_config_writew(bdf, ALIGN_DOWN(pam0, 4) + i*2, pamdata.data16[i]);
<br>
<br>I suspect the fix will require detecting that we aren't running on
<br>QEMU and writing out the data in single bytes.  That way QEMU still
<br>gets the startup speed improvement and the code still runs on Bochs.
</blockquote><p>Kevin, thanks a lot for explaining all of these to me - it was a big help. At the end this was a problem in Bochs that was recently fixed. </p><blockquote><br>Thanks,
<br>-Kevin
<br></blockquote></body></html>