On Mon, 14 Dec 2015 11:22:39 +0300 "Denis V. Lunev" <d...@openvz.org> 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. We are in process of removing static DSDT (ASL template) and replacing it with dynamically generated one. So please do not add new ASL to it, instead of it please redo patch using AML API and it would be better if you do it on top of following series: "[PATCH 00/74] pc: acpi: convert DSDT to AML API and drop ASL templates support" http://qemu.patchew.org/series/%3c1449704528-289297-1-git-send-email-imamm...@redhat.com%3E to avoid touching ASL code and avoid conflicts with API changes Patch also could be simpler if you generate _FDE,_FDI dynamically instead of trying to detect drive presence from guest side. See below for comments. > > 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> > --- > 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) > + } > + } > + Assuming you generate AML dynamically, you can drop above hunks altogether since it's generated by QEMU and you can detect floppy drive presence when building static _FDE. > + 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) > + } replace above function with: uint32_t fde_buf = { fda_present, fdb_present, 0, 0, 0x2}; aml_name_decl("_FDE", aml_buffer(0x14, fde_buf)); > + > + Method(FSTA, 1, NotSerialized) { > + If (LEqual(FDTY(Arg0), 0x00)) { > + Return (0x00) > + } Else { > + Return (0x0F) > + } > + } Drop above, it's not needed, since QEMU does all detection > + > + 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) do the same as with _FDE, the only difference is that instead of buffer place directly encoded package in it, for example look for comment: /* create S3_ / S4_ / S5_ packages if necessary */ also there is no need to make it function, just put _FDI package for a particular floppy drive right inside of it. > + } > + > + 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)) > + } > + } generate a device description only if the corresponding drive is present drop _STA since its assumed that device is present if there isn't _STA object. > } > > Device(LPT) {