qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH for 2.5? 1/1] DSDT: add floppy-related objects


From: Denis V. Lunev
Subject: [Qemu-devel] [PATCH for 2.5? 1/1] DSDT: add floppy-related objects
Date: Mon, 14 Dec 2015 11:22:39 +0300

From: Roman Kagan <address@hidden>

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 <address@hidden>
Signed-off-by: Denis V. Lunev <address@hidden>
CC: Michael S. Tsirkin <address@hidden>
CC: Igor Mammedov <address@hidden>
CC: Paolo Bonzini <address@hidden>
CC: Richard Henderson <address@hidden>
CC: Eduardo Habkost <address@hidden>
---
 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

[Prev in Thread] Current Thread [Next in Thread]