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

Reply via email to