Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread David Woodhouse
On Mon, 2013-02-18 at 23:08 +, David Woodhouse wrote:
 Laszlo has hooked up the RCR on the PIIX3 already, so something like
 this ought to make it reset the PAM setup *only* if reset via that...

 +static void i440fx_reset(DeviceState *ds)
 +{
 +PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, ds);
 +PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev);
 +uint8_t *pci_conf = d-dev.config;
 +
 +if (!d-piix3-rcr_hard_reset)
 +return;
 +

... except that bit (referring to PIIX3 state directly from
i440fx_reset(), having stashed a pointer to it) is horrible.

I've posted a 'cleaner' but much larger and more intrusive patch which
shows how we could introduce a 'reset type' as a proper concept, which
may well be useful for other platforms and situations too.

I'm not too bothered which way we go, but it would be very good to fix
the PAM reset in qemu, because it's a genuine fix and it's *extremely*
convenient to work around the KVM CS segment base bug.

-- 
dwmw2


smime.p7s
Description: S/MIME cryptographic signature
___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread David Woodhouse
On Mon, 2013-02-18 at 17:37 -0500, Kevin O'Connor wrote:
 The ACPI v2 spec describes a hard reset register.  SeaBIOS could
 extract it from the FADT and then use it.  Of course, we'd probably
 want to update the QEMU ACPI tables to implement ACPI v2 then.

This sounded great until I actually came to implement it.

The PIIX reset at 0xcf9 requires *two* writes; one to set the reset type
and then a second write with bit 2 set to actually do the reset.

The ACPI RESET_REG definition only allows for *one* value to be written.

Is that because the PIIX will actually do a hard reset when you write
0x06 to it *anyway*, despite theoretically saying that you should write
0x02 first? Or is the ACPI definition of RESET_REG simply incapable of
being used on the PIIX?

-- 
dwmw2


smime.p7s
Description: S/MIME cryptographic signature
___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread Laszlo Ersek
On 02/19/13 16:29, David Woodhouse wrote:
 On Mon, 2013-02-18 at 17:37 -0500, Kevin O'Connor wrote:
 The ACPI v2 spec describes a hard reset register.  SeaBIOS could
 extract it from the FADT and then use it.  Of course, we'd probably
 want to update the QEMU ACPI tables to implement ACPI v2 then.

 This sounded great until I actually came to implement it.

 The PIIX reset at 0xcf9 requires *two* writes; one to set the reset type
 and then a second write with bit 2 set to actually do the reset.

 The ACPI RESET_REG definition only allows for *one* value to be written.

 Is that because the PIIX will actually do a hard reset when you write
 0x06 to it *anyway*, despite theoretically saying that you should write
 0x02 first? Or is the ACPI definition of RESET_REG simply incapable of
 being used on the PIIX?

The linux kernel actually considers BOOT_ACPI and BOOT_CF9 separate
things; see

- native_machine_emergency_restart() [arch/x86/kernel/reboot.c],
- acpi_reboot() [drivers/acpi/reboot.c],
- acpi_reset() [drivers/acpi/acpica/hwxface.c].

BOOT_ACPI looks like a single write in any case (io space, memory, pci
config).

Funnily enough, on my Thinkpad (
  acpidump --table FACP --binary -o fadt.aml
  iasl -d fadt.aml
):

  /*
   * Intel ACPI Component Architecture
   * AML Disassembler version 20090123
   *
   * Disassembly of fadt.aml, Tue Feb 19 17:13:43 2013
   *
   * ACPI Data Table [FACP]
   *
   * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
   */

  [000h 000  4]Signature : FACP/* Fixed ACPI 
Description Table */

  [070h 112  4]Flags (decoded below) : C2AD
   Reset Register Supported (V2) : 0

  [074h 116 12]   Reset Register : Generic Address Structure
  [074h 116  1] Space ID : 01 (SystemIO)
  [075h 117  1]Bit Width : 08
  [076h 118  1]   Bit Offset : 00
  [077h 119  1] Access Width : 00
  [078h 120  8]  Address : 0CF9
  [080h 128  1] Value to cause reset : 06

Same on my HP Z400. Reset register is not supported, but you could
still write 6 to 0xcf9 :)

I'd say 6 to 0xCF9 is good enough; rcr_write() in qemu is OK with it
too (including your patch at
http://thread.gmane.org/gmane.comp.emulators.qemu/195351/focus=195387.)

Laszlo

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread Gleb Natapov
On Mon, Feb 18, 2013 at 02:33:23PM -0500, Kevin O'Connor wrote:
 On Mon, Feb 18, 2013 at 09:17:05PM +0200, Gleb Natapov wrote:
  On Mon, Feb 18, 2013 at 02:00:52PM -0500, Kevin O'Connor wrote:
   Why not fix KVM so that it runs at fff0 after reset?
   
  Because KVM uses VMX extension and VMX on CPU without unrestricted
  guest is not capable of doing so. Recent KVM code should be able
  to emulate real mode from the fff0 address instead of trying to
  enter vmx guest mode. I asked Laszlo to check if it is so, but even if
  KVM in 3.9 will work it will not fix all existent kernels out there.
  Old behaviour of approximating real mode by vm86 is still supported by
  using emulate_invalid_guest_state=false kernel module option and it will
  be nice if it will not break OVMF since it can be used as a workaround
  in case unemulated instruction is encountered.
 
 For old versions of KVM, SeaBIOS can detect the loop and issue a
 shutdown.  Not nice for users to have their reboot turn into a
 poweroff, but likely better than just a hang.
 
   The only thing SeaBIOS could do is setup the segment registers and
   then jump to fff0, which is a bit of work for the same end result.
   
  If it will jump to fff0 KVM will jump to 0 instead :) It should
  restore pre-CSM loaded OVMF state and reset.
 
 I take it you mean copy 0xfffe to 0xe?  That would not be fun.
 SeaBIOS would need to detect that it's in the state (it's definitely
 not correct to do that on real-hardware or on working kvm
 instances), then setup a trampoline somewhere outside of
 0xe-0xf to do the memcpy, jump to that trampoline, copy the
 memory, restore segment registers, and then jump to 0xfff0.
 That's a lot of kvm specific code to add to seabios as a workaround
 and it seems fragile anyway.
 
Isn't this exactly what qemu_prep_reset() is doing now?

--
Gleb.

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread David Woodhouse
On Tue, 2013-02-19 at 20:13 +0200, Gleb Natapov wrote:
 
  I take it you mean copy 0xfffe to 0xe?  That would not be
 fun.
  SeaBIOS would need to detect that it's in the state (it's definitely
  not correct to do that on real-hardware or on working kvm
  instances), then setup a trampoline somewhere outside of
  0xe-0xf to do the memcpy, jump to that trampoline, copy the
  memory, restore segment registers, and then jump to 0xfff0.
  That's a lot of kvm specific code to add to seabios as a workaround
  and it seems fragile anyway.
  
 Isn't this exactly what qemu_prep_reset() is doing now?

No. It doesn't do the trampoline thing because it doesn't *have* to;
it's copying an identical copy of the code back over itself.

-- 
dwmw2


smime.p7s
Description: S/MIME cryptographic signature
___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread Gleb Natapov
On Tue, Feb 19, 2013 at 06:35:03PM +, David Woodhouse wrote:
 On Tue, 2013-02-19 at 20:13 +0200, Gleb Natapov wrote:
  
   I take it you mean copy 0xfffe to 0xe?  That would not be
  fun.
   SeaBIOS would need to detect that it's in the state (it's definitely
   not correct to do that on real-hardware or on working kvm
   instances), then setup a trampoline somewhere outside of
   0xe-0xf to do the memcpy, jump to that trampoline, copy the
   memory, restore segment registers, and then jump to 0xfff0.
   That's a lot of kvm specific code to add to seabios as a workaround
   and it seems fragile anyway.
   
  Isn't this exactly what qemu_prep_reset() is doing now?
 
 No. It doesn't do the trampoline thing because it doesn't *have* to;
 it's copying an identical copy of the code back over itself.
 
Ah, yes of course. So does CSM takes the whole 0xe-0xf segment or
it leaves OVMF code there somewhere. CSM reset code can jump into OVMF
code in 0xe-0xf range and let it do the copy.

--
Gleb.

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread David Woodhouse
On Tue, 2013-02-19 at 20:41 +0200, Gleb Natapov wrote:
 Ah, yes of course. So does CSM takes the whole 0xe-0xf segment or
 it leaves OVMF code there somewhere. CSM reset code can jump into OVMF
 code in 0xe-0xf range and let it do the copy.

There is no OVMF code there; OVMF doesn't bother to put *anything* into
the RAM at 1MiB-δ unless there's a CSM.

CSM code isn't supposed to be hardware-specific, but I suppose for the
CSM running under KVM case we could *potentially* have a hack at the
reset vector so that when we do find ourselves there under a buggy
qemu/KVM implementation, it could set up a trampoline, reset the PAM
registers manually (so that the KVM CS base address bug doesn't actually
*hurt* us), then try again?

I'd rather implement the 0xcf9 reset properly in qemu though, and make
SeaBIOS use that (which it can do *sanely* as a CSM if it's in the ACPI
tables).

-- 
dwmw2


smime.p7s
Description: S/MIME cryptographic signature
___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread Gleb Natapov
On Tue, Feb 19, 2013 at 06:48:41PM +, David Woodhouse wrote:
 On Tue, 2013-02-19 at 20:41 +0200, Gleb Natapov wrote:
  Ah, yes of course. So does CSM takes the whole 0xe-0xf segment or
  it leaves OVMF code there somewhere. CSM reset code can jump into OVMF
  code in 0xe-0xf range and let it do the copy.
 
 There is no OVMF code there; OVMF doesn't bother to put *anything* into
 the RAM at 1MiB-δ unless there's a CSM.
 
It runs from ROM and do not shadow itself?

 CSM code isn't supposed to be hardware-specific, but I suppose for the
 CSM running under KVM case we could *potentially* have a hack at the
 reset vector so that when we do find ourselves there under a buggy
 qemu/KVM implementation, it could set up a trampoline, reset the PAM
 registers manually (so that the KVM CS base address bug doesn't actually
 *hurt* us), then try again?
 
Yes, we are trying to come up with qemu/KVM specific hack here.

 I'd rather implement the 0xcf9 reset properly in qemu though, and make
 SeaBIOS use that (which it can do *sanely* as a CSM if it's in the ACPI
 tables).
 
I didn't follow that other discussion about hard/soft reset. How proper
0xcf9 reset will fix the problem? What will it do that system_reset does
not?

--
Gleb.

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread David Woodhouse
On Tue, 2013-02-19 at 21:01 +0200, Gleb Natapov wrote:
 On Tue, Feb 19, 2013 at 06:48:41PM +, David Woodhouse wrote:
  On Tue, 2013-02-19 at 20:41 +0200, Gleb Natapov wrote:
   Ah, yes of course. So does CSM takes the whole 0xe-0xf segment or
   it leaves OVMF code there somewhere. CSM reset code can jump into OVMF
   code in 0xe-0xf range and let it do the copy.
  
  There is no OVMF code there; OVMF doesn't bother to put *anything* into
  the RAM at 1MiB-δ unless there's a CSM.
  
 It runs from ROM and do not shadow itself?

It has no need to shadow itself. It loads the SeaBIOS CSM into the range
under 1MiB, if it wants to support legacy BIOS. Other than that, it
never cares about 16-bit code at all.

  I'd rather implement the 0xcf9 reset properly in qemu though, and make
  SeaBIOS use that (which it can do *sanely* as a CSM if it's in the ACPI
  tables).
  
 I didn't follow that other discussion about hard/soft reset. How proper
 0xcf9 reset will fix the problem? What will it do that system_reset does
 not?

A full *hard* reset (0xcf9) will reset the PAM configuration, and thus
the BIOS from 4GiB-δ *would* be shadowed into 1MiB-δ, by hardware.

But qemu doesn't *implement* a full hard reset; it doesn't reset the PAM
registers.

And making it do so the naïve way, by just hooking up a simple device
reset function to do so, would be wrong. Because it *shouldn't* happen
on a soft reset, such as a triple-fault or a reset triggered by the
keyboard controller. Since a soft reset was the only way to get back
from 80286 protected mode to 8086 mode, some software may actually *use*
it and expect it to behave correctly.

Hence the discussion about reset handling.

We'd need to fix SeaBIOS to use the 0xcf9 reset too; currently it'll sit
in an endless loop of keyboard-induced *soft* resets anyway, because it
tries that before 0xcf9.

And in fact it probably shouldn't use the hard-coded 0xcf9 reset; it
should use the one indicated by the ACPI RESET_REG field (which *is*
0xcf9... or should be).

-- 
dwmw2


smime.p7s
Description: S/MIME cryptographic signature
___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread Paolo Bonzini
Il 19/02/2013 20:39, David Woodhouse ha scritto:
 We'd need to fix SeaBIOS to use the 0xcf9 reset too; currently it'll sit
 in an endless loop of keyboard-induced *soft* resets anyway, because it
 tries that before 0xcf9.
 
 And in fact it probably shouldn't use the hard-coded 0xcf9 reset; it
 should use the one indicated by the ACPI RESET_REG field (which *is*
 0xcf9... or should be).

We should implement this: http://mjg59.dreamwidth.org/3561.html

 A while back I did some tests with Windows running on top of qemu.
 This is a great way to evaluate OS behaviour, because you've got
 complete control of what's handed to the OS and what the OS tries to
 do to the hardware. And what I discovered was a little surprising. In
 the absence of an ACPI reboot vector, Windows will hit the keyboard
 controller, wait a while, hit it again and then give up. If an ACPI
 reboot vector is present, windows will poke it, try the keyboard
 controller, poke the ACPI vector again and try the keyboard
 controller one more time.
 
 This turns out to be important. The first thing it means is that it
 generates two writes to the ACPI reboot vector. The second is that it
 leaves a gap between them while it's fiddling with the keyboard
 controller. And, shockingly, it turns out that on most systems the
 ACPI reboot vector points at 0xcf9 in system IO space. Even though
 most implementations nominally require two different values be
 written, it seems that this isn't a strict requirement and the ACPI
 method works.

Paolo

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread David Woodhouse
On Tue, 2013-02-19 at 21:49 +0100, Paolo Bonzini wrote:
  And in fact it probably shouldn't use the hard-coded 0xcf9 reset; it
  should use the one indicated by the ACPI RESET_REG field (which *is*
  0xcf9... or should be).
 
 We should implement this: http://mjg59.dreamwidth.org/3561.html

Matthew fails to distinguish between a hard reset and a soft reset. From
the CSM if we do find ourselves running at 0x0 (which should never
happen except under buggy KVM emulation anyway), we really do need to be
using the 0xcf9 reset (or the ACPI reset, which is going to point to the
same thing in general), and *not* the keyboard reset. And, of course, we
need it to work correctly and reset the PAM configuration (qv).

However, a single bash on the 0xcf9 register ought to suffice so the
ACPI/kbd/ACPI/kbd loop that Matthew describes is probably acceptable. As
long as it does the ACPI one *first*.

( It's also interesting that, as Laszlo observes, machines tend to set
the RESET_REG in the FADT *without* setting the enabled bit in the FADT
flags. Does Windows use it anyway? And is there are reason for *not*
setting the enabled bit, or is it just that all PC BIOSes are written by
crack-smoking hobos that they drag in off the street, and this is just
an artefact of the rule anything they *can* get wrong and still boot
Windows, they *will* get wrong? )


-- 
dwmw2



smime.p7s
Description: S/MIME cryptographic signature
___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-19 Thread Peter Stuge
David Woodhouse wrote:
 is it just that all PC BIOSes are written by crack-smoking hobos
 that they drag in off the street, and this is just an artefact of
 the rule anything they *can* get wrong and still boot Windows,
 they *will* get wrong?

I wouldn't be surprised.


//Peter


pgpMQ0HWnQzGc.pgp
Description: PGP signature
___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-18 Thread Kevin O'Connor
On Mon, Feb 18, 2013 at 08:31:01PM +0200, Gleb Natapov wrote:
 Laszlo explained to me that the problem is that after reset we end up
 in SeaBIOS reset code instead of OVMF one. This is because kvm starts
 to execute from 0 instead of fff0 after reset and this memory
 location is modifying during CSM loading. Seabios solves this problem
 by detecting reset condition and copying pristine image of itself from
 the end of 4G to the end of 1M. OVMF should do the same, but with CSM
 it does not get control back after reset since Seabios reset vector is
 executed instead. Why not put OVMF reset code at reset vector in CSM
 built SeaBIOS to solve the problem?

Why not fix KVM so that it runs at fff0 after reset?

The only thing SeaBIOS could do is setup the segment registers and
then jump to fff0, which is a bit of work for the same end result.

-Kevin

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-18 Thread David Woodhouse
On Mon, 2013-02-18 at 14:00 -0500, Kevin O'Connor wrote:
 On Mon, Feb 18, 2013 at 08:31:01PM +0200, Gleb Natapov wrote:
  Laszlo explained to me that the problem is that after reset we end up
  in SeaBIOS reset code instead of OVMF one. This is because kvm starts
  to execute from 0 instead of fff0 after reset and this memory
  location is modifying during CSM loading. Seabios solves this problem
  by detecting reset condition and copying pristine image of itself from
  the end of 4G to the end of 1M. OVMF should do the same, but with CSM
  it does not get control back after reset since Seabios reset vector is
  executed instead. Why not put OVMF reset code at reset vector in CSM
  built SeaBIOS to solve the problem?
 
 Why not fix KVM so that it runs at fff0 after reset?
 
 The only thing SeaBIOS could do is setup the segment registers and
 then jump to fff0, which is a bit of work for the same end result.

Well, what SeaBIOS already *does* is bash on the keyboard controller to
cause a reset. Which *ought* to work too; I have a patch to at least fix
*that*, by resetting the PAM setup in the i440.

But yes, KVM definitely ought to be running at 0xfff0. This is the
*vm86* code that's broken, not the native KVM version.

-- 
dwmw2


smime.p7s
Description: S/MIME cryptographic signature
___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-18 Thread Laszlo Ersek
On 02/18/13 20:00, Kevin O'Connor wrote:
 On Mon, Feb 18, 2013 at 08:31:01PM +0200, Gleb Natapov wrote:
 Laszlo explained to me that the problem is that after reset we end up
 in SeaBIOS reset code instead of OVMF one. This is because kvm starts
 to execute from 0 instead of fff0 after reset and this memory
 location is modifying during CSM loading. Seabios solves this problem
 by detecting reset condition and copying pristine image of itself from
 the end of 4G to the end of 1M. OVMF should do the same, but with CSM
 it does not get control back after reset since Seabios reset vector is
 executed instead. Why not put OVMF reset code at reset vector in CSM
 built SeaBIOS to solve the problem?
 
 Why not fix KVM so that it runs at fff0 after reset?
 
 The only thing SeaBIOS could do is setup the segment registers and
 then jump to fff0, which is a bit of work for the same end result.

Gleb told me to test under a kvm/next host kernel; there have been many
real-mode related commits. I'll report back.

Laszlo

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-18 Thread Gleb Natapov
On Mon, Feb 18, 2013 at 02:00:52PM -0500, Kevin O'Connor wrote:
 On Mon, Feb 18, 2013 at 08:31:01PM +0200, Gleb Natapov wrote:
  Laszlo explained to me that the problem is that after reset we end up
  in SeaBIOS reset code instead of OVMF one. This is because kvm starts
  to execute from 0 instead of fff0 after reset and this memory
  location is modifying during CSM loading. Seabios solves this problem
  by detecting reset condition and copying pristine image of itself from
  the end of 4G to the end of 1M. OVMF should do the same, but with CSM
  it does not get control back after reset since Seabios reset vector is
  executed instead. Why not put OVMF reset code at reset vector in CSM
  built SeaBIOS to solve the problem?
 
 Why not fix KVM so that it runs at fff0 after reset?
 
Because KVM uses VMX extension and VMX on CPU without unrestricted
guest is not capable of doing so. Recent KVM code should be able
to emulate real mode from the fff0 address instead of trying to
enter vmx guest mode. I asked Laszlo to check if it is so, but even if
KVM in 3.9 will work it will not fix all existent kernels out there.
Old behaviour of approximating real mode by vm86 is still supported by
using emulate_invalid_guest_state=false kernel module option and it will
be nice if it will not break OVMF since it can be used as a workaround
in case unemulated instruction is encountered.

 The only thing SeaBIOS could do is setup the segment registers and
 then jump to fff0, which is a bit of work for the same end result.
 
If it will jump to fff0 KVM will jump to 0 instead :) It should
restore pre-CSM loaded OVMF state and reset.

--
Gleb.

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-18 Thread Kevin O'Connor
On Mon, Feb 18, 2013 at 09:17:05PM +0200, Gleb Natapov wrote:
 On Mon, Feb 18, 2013 at 02:00:52PM -0500, Kevin O'Connor wrote:
  Why not fix KVM so that it runs at fff0 after reset?
  
 Because KVM uses VMX extension and VMX on CPU without unrestricted
 guest is not capable of doing so. Recent KVM code should be able
 to emulate real mode from the fff0 address instead of trying to
 enter vmx guest mode. I asked Laszlo to check if it is so, but even if
 KVM in 3.9 will work it will not fix all existent kernels out there.
 Old behaviour of approximating real mode by vm86 is still supported by
 using emulate_invalid_guest_state=false kernel module option and it will
 be nice if it will not break OVMF since it can be used as a workaround
 in case unemulated instruction is encountered.

For old versions of KVM, SeaBIOS can detect the loop and issue a
shutdown.  Not nice for users to have their reboot turn into a
poweroff, but likely better than just a hang.

  The only thing SeaBIOS could do is setup the segment registers and
  then jump to fff0, which is a bit of work for the same end result.
  
 If it will jump to fff0 KVM will jump to 0 instead :) It should
 restore pre-CSM loaded OVMF state and reset.

I take it you mean copy 0xfffe to 0xe?  That would not be fun.
SeaBIOS would need to detect that it's in the state (it's definitely
not correct to do that on real-hardware or on working kvm
instances), then setup a trampoline somewhere outside of
0xe-0xf to do the memcpy, jump to that trampoline, copy the
memory, restore segment registers, and then jump to 0xfff0.
That's a lot of kvm specific code to add to seabios as a workaround
and it seems fragile anyway.

-Kevin

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-18 Thread Laszlo Ersek
On 02/18/13 20:09, Laszlo Ersek wrote:
 On 02/18/13 20:00, Kevin O'Connor wrote:
 On Mon, Feb 18, 2013 at 08:31:01PM +0200, Gleb Natapov wrote:
 Laszlo explained to me that the problem is that after reset we end up
 in SeaBIOS reset code instead of OVMF one. This is because kvm starts
 to execute from 0 instead of fff0 after reset and this memory
 location is modifying during CSM loading. Seabios solves this problem
 by detecting reset condition and copying pristine image of itself from
 the end of 4G to the end of 1M. OVMF should do the same, but with CSM
 it does not get control back after reset since Seabios reset vector is
 executed instead. Why not put OVMF reset code at reset vector in CSM
 built SeaBIOS to solve the problem?

 Why not fix KVM so that it runs at fff0 after reset?

 The only thing SeaBIOS could do is setup the segment registers and
 then jump to fff0, which is a bit of work for the same end result.
 
 Gleb told me to test under a kvm/next host kernel; there have been many
 real-mode related commits. I'll report back.

I built a host kernel from
http://git.kernel.org/?p=virt/kvm/kvm.git;a=shortlog;h=refs/heads/next, 
currently
at commit cbd29cb6.

The guest reboot works now. :)

Thanks all!
Laszlo

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-18 Thread Kevin O'Connor
On Mon, Feb 18, 2013 at 07:04:08PM +, David Woodhouse wrote:
 Well, what SeaBIOS already *does* is bash on the keyboard controller to
 cause a reset. Which *ought* to work too; I have a patch to at least fix
 *that*, by resetting the PAM setup in the i440.

The thing to be aware of here is that not all resets are equal.  There
is old code out there that will force a reset to go from 80386 mode to
8086 mode (or was it 286 to 8086?).  So, some resets are really
resumes (which must not alter memory) and some are real resets.  It's
a mystery to me which is which, but I know this came up the last time
the QEMU reset logic was discussed.

-Kevin

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-18 Thread David Woodhouse
On Mon, 2013-02-18 at 14:11 -0500, Kevin O'Connor wrote:
 On Mon, Feb 18, 2013 at 07:04:08PM +, David Woodhouse wrote:
  Well, what SeaBIOS already *does* is bash on the keyboard controller to
  cause a reset. Which *ought* to work too; I have a patch to at least fix
  *that*, by resetting the PAM setup in the i440.
 
 The thing to be aware of here is that not all resets are equal.  There
 is old code out there that will force a reset to go from 80386 mode to
 8086 mode (or was it 286 to 8086?).  So, some resets are really
 resumes (which must not alter memory) and some are real resets.  It's
 a mystery to me which is which, but I know this came up the last time
 the QEMU reset logic was discussed.

Hm, yes. It will have been 286 to 8086, because ISTR there was no
*other* way for the CPU to get back from 286 mode.

The i440fx data sheet (§3.0) appears to say that the default values are
loaded on a *hard* reset, not a soft reset. And a reset invoked by the
keyboard controller (as SeaBIOS does) is a *soft* reset. The only way to
do a *hard* reset from software that's mentioned in the datasheet is the
PMC turbo/reset control register (port 0x93). And that, presumably, is
chipset-dependent and not something we can easily use from the reset
vector without doing a bunch of hardware probing.

I suppose we could set it up in advance, during the *first*
initialisation. Just point a 'do_hard_reset()' function pointer at a
function of our choice, perhaps with the existing keyboard reset as a
default if we don't know of anything better.

So we could probably solve the software side, in the guest... but qemu
doesn't seem to distinguish between a hard reset and a soft reset, so
there's no way to make it reset the PAM registers in one case but not
the other. Does this reset for 286-8086 mode actually work in qemu at
all? Is qemu's reset a hard reset, or a soft reset?

I suppose given that the RCR is part of the I440FX, and the behaviour
that we want to vary for hard vs. soft reset is also within the I440FX,
we *could* contrive to reset the PAM registers *only* when reset via the
RCR. But if I propose a patch which does it that way, will someone hunt
me down and hurt me?

-- 
dwmw2


smime.p7s
Description: S/MIME cryptographic signature
___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-18 Thread Kevin O'Connor
On Mon, Feb 18, 2013 at 09:12:46PM +, David Woodhouse wrote:
 The i440fx data sheet (§3.0) appears to say that the default values are
 loaded on a *hard* reset, not a soft reset. And a reset invoked by the
 keyboard controller (as SeaBIOS does) is a *soft* reset. The only way to
 do a *hard* reset from software that's mentioned in the datasheet is the
 PMC turbo/reset control register (port 0x93). And that, presumably, is
 chipset-dependent and not something we can easily use from the reset
 vector without doing a bunch of hardware probing.

The ACPI v2 spec describes a hard reset register.  SeaBIOS could
extract it from the FADT and then use it.  Of course, we'd probably
want to update the QEMU ACPI tables to implement ACPI v2 then.

-Kevin

___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios


Re: [SeaBIOS] [Qemu-devel] [edk2] (PAM stuff) reset doesn't work on OVMF + SeaBIOS CSM

2013-02-18 Thread David Woodhouse
On Mon, 2013-02-18 at 17:37 -0500, Kevin O'Connor wrote:
 On Mon, Feb 18, 2013 at 09:12:46PM +, David Woodhouse wrote:
  The i440fx data sheet (§3.0) appears to say that the default values are
  loaded on a *hard* reset, not a soft reset. And a reset invoked by the
  keyboard controller (as SeaBIOS does) is a *soft* reset. The only way to
  do a *hard* reset from software that's mentioned in the datasheet is the
  PMC turbo/reset control register (port 0x93). And that, presumably, is
  chipset-dependent and not something we can easily use from the reset
  vector without doing a bunch of hardware probing.
 
 The ACPI v2 spec describes a hard reset register.  SeaBIOS could
 extract it from the FADT and then use it.  Of course, we'd probably
 want to update the QEMU ACPI tables to implement ACPI v2 then.

Yeah, that makes me somewhat happier about the SeaBIOS side of it being
hardware-specific. That way the code at the reset vector only has to
cope with a single 8-bit write to memory, IO or config space.

Laszlo has hooked up the RCR on the PIIX3 already, so something like
this ought to make it reset the PAM setup *only* if reset via that...

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 6c77e49..f4420bd 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -77,6 +77,7 @@ typedef struct PIIX3State {
 
 /* Reset Control Register contents */
 uint8_t rcr;
+uint8_t rcr_hard_reset;
 
 /* IO memory region for Reset Control Register (RCR_IOPORT) */
 MemoryRegion rcr_mem;
@@ -84,6 +85,7 @@ typedef struct PIIX3State {
 
 struct PCII440FXState {
 PCIDevice dev;
+PIIX3State *piix3;
 MemoryRegion *system_memory;
 MemoryRegion *pci_address_space;
 MemoryRegion *ram_memory;
@@ -171,6 +173,29 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int 
version_id)
 return 0;
 }
 
+static void i440fx_reset(DeviceState *ds)
+{
+PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, ds);
+PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev);
+uint8_t *pci_conf = d-dev.config;
+
+if (!d-piix3-rcr_hard_reset)
+return;
+
+pci_conf[0x59] = 0x00; // Reset PAM setup
+pci_conf[0x5a] = 0x00;
+pci_conf[0x5b] = 0x00;
+pci_conf[0x5c] = 0x00;
+pci_conf[0x5d] = 0x00;
+pci_conf[0x5e] = 0x00;
+pci_conf[0x5f] = 0x00;
+pci_conf[0x72] = 0x02; // And SMM
+
+i440fx_update_memory_mappings(d);
+
+d-piix3-rcr_hard_reset = 0;
+}
+
 static int i440fx_post_load(void *opaque, int version_id)
 {
 PCII440FXState *d = opaque;
@@ -297,6 +322,7 @@ static PCIBus *i440fx_common_init(const char *device_name,
 pci_bus_set_route_irq_fn(b, piix3_route_intx_pin_to_irq);
 }
 piix3-pic = pic;
+f-piix3 = piix3;
 *isa_bus = DO_UPCAST(ISABus, qbus,
  qdev_get_child_bus(piix3-dev.qdev, isa.0));
 
@@ -521,6 +547,8 @@ static void rcr_write(void *opaque, hwaddr addr, uint64_t 
val, unsigned len)
 PIIX3State *d = opaque;
 
 if (val  4) {
+if (val  2)
+d-rcr_hard_reset = 1;
 qemu_system_reset_request();
 return;
 }
@@ -615,6 +643,7 @@ static void i440fx_class_init(ObjectClass *klass, void 
*data)
 dc-desc = Host bridge;
 dc-no_user = 1;
 dc-vmsd = vmstate_i440fx;
+dc-reset = i440fx_reset;
 }
 
 static const TypeInfo i440fx_info = {


-- 
dwmw2



smime.p7s
Description: S/MIME cryptographic signature
___
SeaBIOS mailing list
SeaBIOS@seabios.org
http://www.seabios.org/mailman/listinfo/seabios