On Mon, Dec 14, 2015 at 11:22:39AM +0300, Denis V. Lunev wrote: > From: Roman Kagan <rka...@virtuozzo.com> > > On x86-based systems Linux determines the presence and the type of > floppy drives via a query of a CMOS field. So does SeaBIOS when > populating the return data for int 0x13 function 0x08. > > Windows doesn't; instead, it requests this information from BIOS via int > 0x13/0x08 or through ACPI objects _FDE (Floppy Drive Enumerate) and _FDI > (Floppy Drive Information). On UEFI systems only ACPI-based detection > is supported. > > QEMU used not to provide those objects in its DSDT; as a result floppy > drives were invisible to Windows on UEFI/OVMF. > > This patch implements those objects in ASL, making the ACPI interpreter > query the CMOS field and populate the objects. The data values used for > _FDI (which, per ACPI spec, is supposed to be equivalent to BIOS int > 0x13/0x08) are taken from SeaBIOS. > > Signed-off-by: Roman Kagan <rka...@virtuozzo.com> > Signed-off-by: Denis V. Lunev <d...@openvz.org> > CC: Michael S. Tsirkin <m...@redhat.com> > CC: Igor Mammedov <imamm...@redhat.com> > CC: Paolo Bonzini <pbonz...@redhat.com> > CC: Richard Henderson <r...@twiddle.net> > CC: Eduardo Habkost <ehabk...@redhat.com>
This is not a regression, so I'm inclined not to merge this for 2.5. Pls correct me if I'm wrong. > --- > hw/i386/acpi-dsdt-isa.dsl | 109 > ++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 109 insertions(+) > > diff --git a/hw/i386/acpi-dsdt-isa.dsl b/hw/i386/acpi-dsdt-isa.dsl > index 89caa16..8b03e2b 100644 > --- a/hw/i386/acpi-dsdt-isa.dsl > +++ b/hw/i386/acpi-dsdt-isa.dsl > @@ -23,6 +23,8 @@ Scope(\_SB.PCI0.ISA) { > IRQNoFlags() { 8 } > IO(Decode16, 0x0072, 0x0072, 0x02, 0x06) > }) > + > + OperationRegion(CMS0, SystemCMOS, Zero, 0x40) > } > > Device(KBD) { > @@ -63,6 +65,113 @@ Scope(\_SB.PCI0.ISA) { > IRQNoFlags() { 6 } > DMA(Compatibility, NotBusMaster, Transfer8) { 2 } > }) > + > + Field(^RTC.CMS0, ByteAcc, NoLock, Preserve) { > + Offset(0x10), > + FDTS, 8 > + } > + > + Method(FDTY, 1, NotSerialized) { > + If (LEqual(Arg0, 0x00)) { > + Return (And(ShiftRight(FDTS, 0x04), 0x0F)) > + } ElseIf (LEqual(Arg0, 0x01)) { > + Return (And(FDTS, 0x0F)) > + } Else { > + Return (0x00) > + } > + } > + > + Method(_FDE, 0, NotSerialized) { > + Store(Buffer(0x14) {}, Local0) > + CreateDWordField(Local0, 0x00, FDAE) > + CreateDWordField(Local0, 0x04, FDBE) > + CreateDWordField(Local0, 0x10, TAPE) > + > + If (LNotEqual(FDTY(0x00), 0)) { > + Store(0x01, FDAE) > + } > + If (LNotEqual(FDTY(0x01), 0)) { > + Store(0x01, FDBE) > + } > + Store(0x02, TAPE) > + > + Return (Local0) > + } > + > + Method(FSTA, 1, NotSerialized) { > + If (LEqual(FDTY(Arg0), 0x00)) { > + Return (0x00) > + } Else { > + Return (0x0F) > + } > + } > + > + Method(XFDI, 1, NotSerialized) { > + Store(FDTY(Arg0), Local0) > + > + Store(Package (0x10) { > + 0x00, // Drive Number > + 0x00, // Device Type > + 0x00, // Maximum Cylinder Number > + 0x00, // Maximum Sector Number > + 0x00, // Maximum Head Number > + /* SeaBIOS uses the below values regardless of the drive > + * type, so shall we */ > + 0xAF, // disk_specify_1 > + 0x02, // disk_specify_2 > + 0x25, // disk_motor_wait > + 0x02, // disk_sector_siz > + 0x12, // disk_eot > + 0x1B, // disk_rw_gap > + 0xFF, // disk_dtl > + 0x6C, // disk_formt_gap > + 0xF6, // disk_fill > + 0x0F, // disk_head_sttl > + 0x08, // disk_motor_strt > + }, Local1) > + > + Store(Arg0, Index(Local1, 0x00)) > + Store(Local0, Index(Local1, 0x01)) > + > + If (LEqual(Local0, 4)) { > + /* 1.44 Mb 3"5 drive */ > + Store(0x4F, Index(Local1, 0x02)) > + Store(0x12, Index(Local1, 0x03)) > + Store(0x01, Index(Local1, 0x04)) > + } ElseIf (LEqual(Local0, 5)) { > + /* 2.88 Mb 3"5 drive */ > + Store(0x4F, Index(Local1, 0x02)) > + Store(0x24, Index(Local1, 0x03)) > + Store(0x01, Index(Local1, 0x04)) > + } ElseIf (LEqual(Local0, 2)) { > + /* 1.2 Mb 5"5 drive */ > + Store(0x4F, Index(Local1, 0x02)) > + Store(0x0F, Index(Local1, 0x03)) > + Store(0x01, Index(Local1, 0x04)) > + } > + > + Return (Local1) > + } > + > + Device(FLPA) { > + Name(_ADR, 0x00) > + Method(_STA, 0, NotSerialized) { > + Return (FSTA(_ADR)) > + } > + Method(_FDI, 0, NotSerialized) { > + Return (XFDI(_ADR)) > + } > + } > + > + Device(FLPB) { > + Name(_ADR, 0x01) > + Method(_STA, 0, NotSerialized) { > + Return (FSTA(_ADR)) > + } > + Method(_FDI, 0, NotSerialized) { > + Return (XFDI(_ADR)) > + } > + } > } > > Device(LPT) { > -- > 2.1.4