diff mbox series

[4/4] hw/block/fdc: Extract SysBus floppy controllers to fdc-sysbus.c

Message ID 20210415102321.3987935-5-philmd@redhat.com (mailing list archive)
State New, archived
Headers show
Series hw/block/fdc: Allow Kconfig-selecting ISA bus/SysBus floppy controllers | expand

Commit Message

Philippe Mathieu-Daudé April 15, 2021, 10:23 a.m. UTC
Some machines use floppy controllers via the SysBus interface,
and don't need to pull in all the SysBus code.
Extract the SysBus specific code to a new unit: fdc-sysbus.c,
and add a new Kconfig symbol: "FDC_SYSBUS".

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 hw/block/fdc-sysbus.c | 252 ++++++++++++++++++++++++++++++++++++++++++
 hw/block/fdc.c        | 220 ------------------------------------
 MAINTAINERS           |   1 +
 hw/block/Kconfig      |   4 +
 hw/block/meson.build  |   1 +
 hw/block/trace-events |   2 +
 hw/mips/Kconfig       |   2 +-
 hw/sparc/Kconfig      |   2 +-
 8 files changed, 262 insertions(+), 222 deletions(-)
 create mode 100644 hw/block/fdc-sysbus.c

Comments

John Snow April 27, 2021, 5:34 p.m. UTC | #1
On 4/15/21 6:23 AM, Philippe Mathieu-Daudé wrote:
> Some machines use floppy controllers via the SysBus interface,
> and don't need to pull in all the SysBus code.
> Extract the SysBus specific code to a new unit: fdc-sysbus.c,
> and add a new Kconfig symbol: "FDC_SYSBUS".
> 
> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>

LGTM, but again you'll want someone to review the Kconfig changes. It 
looks reasonable to me at a glance, but I just don't know what I don't 
know there.

I'm trusting you somewhat that you've audited the proper dependencies 
for each subsystem and that these have been accurately described via 
Kconfig -- my knowledge of non-x86 platforms is a bit meager, so I am 
relying on CI to tell me if this breaks anything I care about.

Would love to get an ACK from Mark Cave-Ayland and Hervé Poussineau if 
possible, but if they're not available to take a quick peek, we'll try 
to get this in closer to the beginning of the dev window to maximize 
problem-finding time.

Reviewed-by: John Snow <jsnow@redhat.com>

> ---
>   hw/block/fdc-sysbus.c | 252 ++++++++++++++++++++++++++++++++++++++++++
>   hw/block/fdc.c        | 220 ------------------------------------
>   MAINTAINERS           |   1 +
>   hw/block/Kconfig      |   4 +
>   hw/block/meson.build  |   1 +
>   hw/block/trace-events |   2 +
>   hw/mips/Kconfig       |   2 +-
>   hw/sparc/Kconfig      |   2 +-
>   8 files changed, 262 insertions(+), 222 deletions(-)
>   create mode 100644 hw/block/fdc-sysbus.c
> 
> diff --git a/hw/block/fdc-sysbus.c b/hw/block/fdc-sysbus.c
> new file mode 100644
> index 00000000000..71755fd6ae4
> --- /dev/null
> +++ b/hw/block/fdc-sysbus.c
> @@ -0,0 +1,252 @@
> +/*
> + * QEMU Floppy disk emulator (Intel 82078)
> + *
> + * Copyright (c) 2003, 2007 Jocelyn Mayer
> + * Copyright (c) 2008 Hervé Poussineau
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "qom/object.h"
> +#include "hw/sysbus.h"
> +#include "hw/block/fdc.h"
> +#include "migration/vmstate.h"
> +#include "fdc-internal.h"
> +#include "trace.h"
> +
> +#define TYPE_SYSBUS_FDC "base-sysbus-fdc"
> +typedef struct FDCtrlSysBusClass FDCtrlSysBusClass;
> +typedef struct FDCtrlSysBus FDCtrlSysBus;
> +DECLARE_OBJ_CHECKERS(FDCtrlSysBus, FDCtrlSysBusClass,
> +                     SYSBUS_FDC, TYPE_SYSBUS_FDC)
> +
> +struct FDCtrlSysBusClass {
> +    /*< private >*/
> +    SysBusDeviceClass parent_class;
> +    /*< public >*/
> +
> +    bool use_strict_io;
> +};
> +
> +struct FDCtrlSysBus {
> +    /*< private >*/
> +    SysBusDevice parent_obj;
> +    /*< public >*/
> +
> +    struct FDCtrl state;
> +};
> +
> +static uint64_t fdctrl_read_mem(void *opaque, hwaddr reg, unsigned ize)
> +{
> +    return fdctrl_read(opaque, (uint32_t)reg);
> +}
> +
> +static void fdctrl_write_mem(void *opaque, hwaddr reg,
> +                             uint64_t value, unsigned size)
> +{
> +    fdctrl_write(opaque, (uint32_t)reg, value);
> +}
> +
> +static const MemoryRegionOps fdctrl_mem_ops = {
> +    .read = fdctrl_read_mem,
> +    .write = fdctrl_write_mem,
> +    .endianness = DEVICE_NATIVE_ENDIAN,
> +};
> +
> +static const MemoryRegionOps fdctrl_mem_strict_ops = {
> +    .read = fdctrl_read_mem,
> +    .write = fdctrl_write_mem,
> +    .endianness = DEVICE_NATIVE_ENDIAN,
> +    .valid = {
> +        .min_access_size = 1,
> +        .max_access_size = 1,
> +    },
> +};
> +
> +static void fdctrl_external_reset_sysbus(DeviceState *d)
> +{
> +    FDCtrlSysBus *sys = SYSBUS_FDC(d);
> +    FDCtrl *s = &sys->state;
> +
> +    fdctrl_reset(s, 0);
> +}
> +
> +static void fdctrl_handle_tc(void *opaque, int irq, int level)
> +{
> +    trace_fdctrl_tc_pulse(level);
> +}
> +
> +void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
> +                        hwaddr mmio_base, DriveInfo **fds)
> +{
> +    FDCtrl *fdctrl;
> +    DeviceState *dev;
> +    SysBusDevice *sbd;
> +    FDCtrlSysBus *sys;
> +
> +    dev = qdev_new("sysbus-fdc");
> +    sys = SYSBUS_FDC(dev);
> +    fdctrl = &sys->state;
> +    fdctrl->dma_chann = dma_chann; /* FIXME */
> +    sbd = SYS_BUS_DEVICE(dev);
> +    sysbus_realize_and_unref(sbd, &error_fatal);
> +    sysbus_connect_irq(sbd, 0, irq);
> +    sysbus_mmio_map(sbd, 0, mmio_base);
> +
> +    fdctrl_init_drives(&sys->state.bus, fds);
> +}
> +
> +void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
> +                       DriveInfo **fds, qemu_irq *fdc_tc)
> +{
> +    DeviceState *dev;
> +    FDCtrlSysBus *sys;
> +
> +    dev = qdev_new("sun-fdtwo");
> +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> +    sys = SYSBUS_FDC(dev);
> +    sysbus_connect_irq(SYS_BUS_DEVICE(sys), 0, irq);
> +    sysbus_mmio_map(SYS_BUS_DEVICE(sys), 0, io_base);
> +    *fdc_tc = qdev_get_gpio_in(dev, 0);
> +
> +    fdctrl_init_drives(&sys->state.bus, fds);
> +}
> +
> +static void sysbus_fdc_common_initfn(Object *obj)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    FDCtrlSysBusClass *sbdc = SYSBUS_FDC_GET_CLASS(obj);
> +    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> +    FDCtrlSysBus *sys = SYSBUS_FDC(obj);
> +    FDCtrl *fdctrl = &sys->state;
> +
> +    fdctrl->dma_chann = -1;
> +
> +    qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */
> +
> +    memory_region_init_io(&fdctrl->iomem, obj,
> +                          sbdc->use_strict_io ? &fdctrl_mem_strict_ops
> +                                              : &fdctrl_mem_ops,
> +                          fdctrl, "fdc", 0x08);
> +    sysbus_init_mmio(sbd, &fdctrl->iomem);
> +
> +    sysbus_init_irq(sbd, &fdctrl->irq);
> +    qdev_init_gpio_in(dev, fdctrl_handle_tc, 1);
> +}
> +
> +static void sysbus_fdc_common_realize(DeviceState *dev, Error **errp)
> +{
> +    FDCtrlSysBus *sys = SYSBUS_FDC(dev);
> +    FDCtrl *fdctrl = &sys->state;
> +
> +    fdctrl_realize_common(dev, fdctrl, errp);
> +}
> +
> +static const VMStateDescription vmstate_sysbus_fdc = {
> +    .name = "fdc",
> +    .version_id = 2,
> +    .minimum_version_id = 2,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +static Property sysbus_fdc_properties[] = {
> +    DEFINE_PROP_SIGNED("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type,
> +                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
> +                        FloppyDriveType),
> +    DEFINE_PROP_SIGNED("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type,
> +                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
> +                        FloppyDriveType),
> +    DEFINE_PROP_SIGNED("fallback", FDCtrlSysBus, state.fallback,
> +                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
> +                        FloppyDriveType),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    device_class_set_props(dc, sysbus_fdc_properties);
> +    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> +}
> +
> +static const TypeInfo sysbus_fdc_info = {
> +    .name          = "sysbus-fdc",
> +    .parent        = TYPE_SYSBUS_FDC,
> +    .class_init    = sysbus_fdc_class_init,
> +};
> +
> +static void sysbus_fdc_common_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->realize = sysbus_fdc_common_realize;
> +    dc->reset = fdctrl_external_reset_sysbus;
> +    dc->vmsd = &vmstate_sysbus_fdc;
> +}
> +
> +static const TypeInfo sysbus_fdc_type_info = {
> +    .name          = TYPE_SYSBUS_FDC,
> +    .parent        = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(FDCtrlSysBus),
> +    .instance_init = sysbus_fdc_common_initfn,
> +    .abstract      = true,
> +    .class_init    = sysbus_fdc_common_class_init,
> +    .class_size    = sizeof(FDCtrlSysBusClass),
> +};
> +
> +static Property sun4m_fdc_properties[] = {
> +    DEFINE_PROP_SIGNED("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type,
> +                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
> +                        FloppyDriveType),
> +    DEFINE_PROP_SIGNED("fallback", FDCtrlSysBus, state.fallback,
> +                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
> +                        FloppyDriveType),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
> +{
> +    FDCtrlSysBusClass *sbdc = SYSBUS_FDC_CLASS(klass);
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    sbdc->use_strict_io = true;
> +    device_class_set_props(dc, sun4m_fdc_properties);
> +    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> +}
> +
> +static const TypeInfo sun4m_fdc_info = {
> +    .name          = "sun-fdtwo",
> +    .parent        = TYPE_SYSBUS_FDC,
> +    .class_init    = sun4m_fdc_class_init,
> +};
> +
> +static void sysbus_fdc_register_types(void)
> +{
> +    type_register_static(&sun4m_fdc_info);
> +    type_register_static(&sysbus_fdc_type_info);
> +    type_register_static(&sysbus_fdc_info);
> +}
> +
> +type_init(sysbus_fdc_register_types)
> diff --git a/hw/block/fdc.c b/hw/block/fdc.c
> index 50567d972ff..64af4d194ce 100644
> --- a/hw/block/fdc.c
> +++ b/hw/block/fdc.c
> @@ -36,7 +36,6 @@
>   #include "hw/isa/isa.h"
>   #include "hw/qdev-properties.h"
>   #include "hw/qdev-properties-system.h"
> -#include "hw/sysbus.h"
>   #include "migration/vmstate.h"
>   #include "hw/block/block.h"
>   #include "sysemu/block-backend.h"
> @@ -775,17 +774,6 @@ static FloppyDriveType get_fallback_drive_type(FDrive *drv)
>       return drv->fdctrl->fallback;
>   }
>   
> -#define TYPE_SYSBUS_FDC "base-sysbus-fdc"
> -OBJECT_DECLARE_SIMPLE_TYPE(FDCtrlSysBus, SYSBUS_FDC)
> -
> -struct FDCtrlSysBus {
> -    /*< private >*/
> -    SysBusDevice parent_obj;
> -    /*< public >*/
> -
> -    struct FDCtrl state;
> -};
> -
>   uint32_t fdctrl_read(void *opaque, uint32_t reg)
>   {
>       FDCtrl *fdctrl = opaque;
> @@ -850,34 +838,6 @@ void fdctrl_write(void *opaque, uint32_t reg, uint32_t value)
>       }
>   }
>   
> -static uint64_t fdctrl_read_mem (void *opaque, hwaddr reg,
> -                                 unsigned ize)
> -{
> -    return fdctrl_read(opaque, (uint32_t)reg);
> -}
> -
> -static void fdctrl_write_mem (void *opaque, hwaddr reg,
> -                              uint64_t value, unsigned size)
> -{
> -    fdctrl_write(opaque, (uint32_t)reg, value);
> -}
> -
> -static const MemoryRegionOps fdctrl_mem_ops = {
> -    .read = fdctrl_read_mem,
> -    .write = fdctrl_write_mem,
> -    .endianness = DEVICE_NATIVE_ENDIAN,
> -};
> -
> -static const MemoryRegionOps fdctrl_mem_strict_ops = {
> -    .read = fdctrl_read_mem,
> -    .write = fdctrl_write_mem,
> -    .endianness = DEVICE_NATIVE_ENDIAN,
> -    .valid = {
> -        .min_access_size = 1,
> -        .max_access_size = 1,
> -    },
> -};
> -
>   static bool fdrive_media_changed_needed(void *opaque)
>   {
>       FDrive *drive = opaque;
> @@ -1101,19 +1061,6 @@ const VMStateDescription vmstate_fdc = {
>       }
>   };
>   
> -static void fdctrl_external_reset_sysbus(DeviceState *d)
> -{
> -    FDCtrlSysBus *sys = SYSBUS_FDC(d);
> -    FDCtrl *s = &sys->state;
> -
> -    fdctrl_reset(s, 0);
> -}
> -
> -static void fdctrl_handle_tc(void *opaque, int irq, int level)
> -{
> -    trace_fdctrl_tc_pulse(level);
> -}
> -
>   /* Change IRQ state */
>   static void fdctrl_reset_irq(FDCtrl *fdctrl)
>   {
> @@ -2370,42 +2317,6 @@ void fdctrl_init_drives(FloppyBus *bus, DriveInfo **fds)
>       }
>   }
>   
> -void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
> -                        hwaddr mmio_base, DriveInfo **fds)
> -{
> -    FDCtrl *fdctrl;
> -    DeviceState *dev;
> -    SysBusDevice *sbd;
> -    FDCtrlSysBus *sys;
> -
> -    dev = qdev_new("sysbus-fdc");
> -    sys = SYSBUS_FDC(dev);
> -    fdctrl = &sys->state;
> -    fdctrl->dma_chann = dma_chann; /* FIXME */
> -    sbd = SYS_BUS_DEVICE(dev);
> -    sysbus_realize_and_unref(sbd, &error_fatal);
> -    sysbus_connect_irq(sbd, 0, irq);
> -    sysbus_mmio_map(sbd, 0, mmio_base);
> -
> -    fdctrl_init_drives(&sys->state.bus, fds);
> -}
> -
> -void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
> -                       DriveInfo **fds, qemu_irq *fdc_tc)
> -{
> -    DeviceState *dev;
> -    FDCtrlSysBus *sys;
> -
> -    dev = qdev_new("sun-fdtwo");
> -    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> -    sys = SYSBUS_FDC(dev);
> -    sysbus_connect_irq(SYS_BUS_DEVICE(sys), 0, irq);
> -    sysbus_mmio_map(SYS_BUS_DEVICE(sys), 0, io_base);
> -    *fdc_tc = qdev_get_gpio_in(dev, 0);
> -
> -    fdctrl_init_drives(&sys->state.bus, fds);
> -}
> -
>   void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl, Error **errp)
>   {
>       int i, j;
> @@ -2458,139 +2369,8 @@ void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl, Error **errp)
>       }
>   }
>   
> -static void sysbus_fdc_initfn(Object *obj)
> -{
> -    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
> -    FDCtrlSysBus *sys = SYSBUS_FDC(obj);
> -    FDCtrl *fdctrl = &sys->state;
> -
> -    fdctrl->dma_chann = -1;
> -
> -    memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_ops, fdctrl,
> -                          "fdc", 0x08);
> -    sysbus_init_mmio(sbd, &fdctrl->iomem);
> -}
> -
> -static void sun4m_fdc_initfn(Object *obj)
> -{
> -    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
> -    FDCtrlSysBus *sys = SYSBUS_FDC(obj);
> -    FDCtrl *fdctrl = &sys->state;
> -
> -    fdctrl->dma_chann = -1;
> -
> -    memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_strict_ops,
> -                          fdctrl, "fdctrl", 0x08);
> -    sysbus_init_mmio(sbd, &fdctrl->iomem);
> -}
> -
> -static void sysbus_fdc_common_initfn(Object *obj)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> -    FDCtrlSysBus *sys = SYSBUS_FDC(obj);
> -    FDCtrl *fdctrl = &sys->state;
> -
> -    qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */
> -
> -    sysbus_init_irq(sbd, &fdctrl->irq);
> -    qdev_init_gpio_in(dev, fdctrl_handle_tc, 1);
> -}
> -
> -static void sysbus_fdc_common_realize(DeviceState *dev, Error **errp)
> -{
> -    FDCtrlSysBus *sys = SYSBUS_FDC(dev);
> -    FDCtrl *fdctrl = &sys->state;
> -
> -    fdctrl_realize_common(dev, fdctrl, errp);
> -}
> -
> -static const VMStateDescription vmstate_sysbus_fdc ={
> -    .name = "fdc",
> -    .version_id = 2,
> -    .minimum_version_id = 2,
> -    .fields = (VMStateField[]) {
> -        VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
> -        VMSTATE_END_OF_LIST()
> -    }
> -};
> -
> -static Property sysbus_fdc_properties[] = {
> -    DEFINE_PROP_SIGNED("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type,
> -                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
> -                        FloppyDriveType),
> -    DEFINE_PROP_SIGNED("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type,
> -                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
> -                        FloppyDriveType),
> -    DEFINE_PROP_SIGNED("fallback", FDCtrlSysBus, state.fallback,
> -                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
> -                        FloppyDriveType),
> -    DEFINE_PROP_END_OF_LIST(),
> -};
> -
> -static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
> -{
> -    DeviceClass *dc = DEVICE_CLASS(klass);
> -
> -    device_class_set_props(dc, sysbus_fdc_properties);
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> -}
> -
> -static const TypeInfo sysbus_fdc_info = {
> -    .name          = "sysbus-fdc",
> -    .parent        = TYPE_SYSBUS_FDC,
> -    .instance_init = sysbus_fdc_initfn,
> -    .class_init    = sysbus_fdc_class_init,
> -};
> -
> -static Property sun4m_fdc_properties[] = {
> -    DEFINE_PROP_SIGNED("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type,
> -                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
> -                        FloppyDriveType),
> -    DEFINE_PROP_SIGNED("fallback", FDCtrlSysBus, state.fallback,
> -                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
> -                        FloppyDriveType),
> -    DEFINE_PROP_END_OF_LIST(),
> -};
> -
> -static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
> -{
> -    DeviceClass *dc = DEVICE_CLASS(klass);
> -
> -    device_class_set_props(dc, sun4m_fdc_properties);
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> -}
> -
> -static const TypeInfo sun4m_fdc_info = {
> -    .name          = "sun-fdtwo",
> -    .parent        = TYPE_SYSBUS_FDC,
> -    .instance_init = sun4m_fdc_initfn,
> -    .class_init    = sun4m_fdc_class_init,
> -};
> -
> -static void sysbus_fdc_common_class_init(ObjectClass *klass, void *data)
> -{
> -    DeviceClass *dc = DEVICE_CLASS(klass);
> -
> -    dc->realize = sysbus_fdc_common_realize;
> -    dc->reset = fdctrl_external_reset_sysbus;
> -    dc->vmsd = &vmstate_sysbus_fdc;
> -}
> -
> -static const TypeInfo sysbus_fdc_type_info = {
> -    .name          = TYPE_SYSBUS_FDC,
> -    .parent        = TYPE_SYS_BUS_DEVICE,
> -    .instance_size = sizeof(FDCtrlSysBus),
> -    .instance_init = sysbus_fdc_common_initfn,
> -    .abstract      = true,
> -    .class_init    = sysbus_fdc_common_class_init,
> -};
> -
>   static void fdc_register_types(void)
>   {
> -    type_register_static(&sysbus_fdc_type_info);
> -    type_register_static(&sysbus_fdc_info);
> -    type_register_static(&sun4m_fdc_info);
>       type_register_static(&floppy_bus_info);
>       type_register_static(&floppy_drive_info);
>   }
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e7ed334f586..0a908c22103 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1678,6 +1678,7 @@ S: Supported
>   F: hw/block/fdc.c
>   F: hw/block/fdc-internal.h
>   F: hw/block/fdc-isa.c
> +F: hw/block/fdc-sysbus.c
>   F: include/hw/block/fdc.h
>   F: tests/qtest/fdc-test.c
>   T: git https://gitlab.com/jsnow/qemu.git ide
> diff --git a/hw/block/Kconfig b/hw/block/Kconfig
> index 0a2c046fa6c..d50be837666 100644
> --- a/hw/block/Kconfig
> +++ b/hw/block/Kconfig
> @@ -8,6 +8,10 @@ config FDC_ISA
>       # select ISA_BUS here instead of polluting each board that requires one
>       select ISA_BUS
>   
> +config FDC_SYSBUS
> +    bool
> +    select FDC
> +
>   config SSI_M25P80
>       bool
>   
> diff --git a/hw/block/meson.build b/hw/block/meson.build
> index f33a665c945..c3935350485 100644
> --- a/hw/block/meson.build
> +++ b/hw/block/meson.build
> @@ -6,6 +6,7 @@
>   softmmu_ss.add(when: 'CONFIG_ECC', if_true: files('ecc.c'))
>   softmmu_ss.add(when: 'CONFIG_FDC', if_true: files('fdc.c'))
>   softmmu_ss.add(when: 'CONFIG_FDC_ISA', if_true: files('fdc-isa.c'))
> +softmmu_ss.add(when: 'CONFIG_FDC_SYSBUS', if_true: files('fdc-sysbus.c'))
>   softmmu_ss.add(when: 'CONFIG_NAND', if_true: files('nand.c'))
>   softmmu_ss.add(when: 'CONFIG_ONENAND', if_true: files('onenand.c'))
>   softmmu_ss.add(when: 'CONFIG_PFLASH_CFI01', if_true: files('pflash_cfi01.c'))
> diff --git a/hw/block/trace-events b/hw/block/trace-events
> index 306989c193c..266b34393a3 100644
> --- a/hw/block/trace-events
> +++ b/hw/block/trace-events
> @@ -3,6 +3,8 @@
>   # fdc.c
>   fdc_ioport_read(uint8_t reg, uint8_t value) "read reg 0x%02x val 0x%02x"
>   fdc_ioport_write(uint8_t reg, uint8_t value) "write reg 0x%02x val 0x%02x"
> +
> +# fdc-sysbus.c
>   fdctrl_tc_pulse(int level) "TC pulse: %u"
>   
>   # pflash_cfi01.c
> diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
> index aadd436bf4e..c245e881a2b 100644
> --- a/hw/mips/Kconfig
> +++ b/hw/mips/Kconfig
> @@ -20,7 +20,7 @@ config JAZZ
>       select G364FB
>       select DP8393X
>       select ESP
> -    select FDC
> +    select FDC_SYSBUS
>       select MC146818RTC
>       select PCKBD
>       select SERIAL
> diff --git a/hw/sparc/Kconfig b/hw/sparc/Kconfig
> index 8dcb10086fd..79d58beb7a6 100644
> --- a/hw/sparc/Kconfig
> +++ b/hw/sparc/Kconfig
> @@ -8,7 +8,7 @@ config SUN4M
>       select UNIMP
>       select ESCC
>       select ESP
> -    select FDC
> +    select FDC_SYSBUS
>       select SLAVIO
>       select LANCE
>       select M48T59
>
Philippe Mathieu-Daudé April 28, 2021, 12:30 p.m. UTC | #2
On 4/27/21 7:34 PM, John Snow wrote:
> On 4/15/21 6:23 AM, Philippe Mathieu-Daudé wrote:
>> Some machines use floppy controllers via the SysBus interface,
>> and don't need to pull in all the SysBus code.
>> Extract the SysBus specific code to a new unit: fdc-sysbus.c,
>> and add a new Kconfig symbol: "FDC_SYSBUS".
>>
>> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> 
> LGTM, but again you'll want someone to review the Kconfig changes. It
> looks reasonable to me at a glance, but I just don't know what I don't
> know there.
> 
> I'm trusting you somewhat that you've audited the proper dependencies
> for each subsystem and that these have been accurately described via
> Kconfig -- my knowledge of non-x86 platforms is a bit meager, so I am
> relying on CI to tell me if this breaks anything I care about.

The way I test these Kconfig changes is configuring with
--without-default-devices, and build/test for each machine doing:

$ echo $MACHINE=y > default-configs/devices/$arch-softmmu.mak

(I overwrite because currently we don't support having a base
config different than the default-configs one).

For example for the SPARCbook machine:

$ echo CONFIG_SUN4M=y > default-configs/devices/sparc-softmmu.mak
$ ninja qemu-system-sparc
$ qemu-system-sparc -M SPARCbook -S

Or for the Jazz machine:

$ echo CONFIG_JAZZ=y > default-configs/devices/mips64el-softmmu.mak
$ echo CONFIG_SEMIHOSTING=y >> default-configs/devices/mips64el-softmmu.mak
$ ninja qemu-system-mips64el
$ ./qemu-system-mips64el -M pica61 -S

(The CONFIG_SEMIHOSTING is a particular kludge pending another series)

But unfortunately there are predating bugs breaking this testing.

I'll add this information in the respin's cover.

> Would love to get an ACK from Mark Cave-Ayland and Hervé Poussineau if
> possible, but if they're not available to take a quick peek, we'll try
> to get this in closer to the beginning of the dev window to maximize
> problem-finding time.

The sun4m maintainer is Artyom.

> Reviewed-by: John Snow <jsnow@redhat.com>

Thanks!

> 
>> ---
>>   hw/block/fdc-sysbus.c | 252 ++++++++++++++++++++++++++++++++++++++++++
>>   hw/block/fdc.c        | 220 ------------------------------------
>>   MAINTAINERS           |   1 +
>>   hw/block/Kconfig      |   4 +
>>   hw/block/meson.build  |   1 +
>>   hw/block/trace-events |   2 +
>>   hw/mips/Kconfig       |   2 +-
>>   hw/sparc/Kconfig      |   2 +-
>>   8 files changed, 262 insertions(+), 222 deletions(-)
>>   create mode 100644 hw/block/fdc-sysbus.c
diff mbox series

Patch

diff --git a/hw/block/fdc-sysbus.c b/hw/block/fdc-sysbus.c
new file mode 100644
index 00000000000..71755fd6ae4
--- /dev/null
+++ b/hw/block/fdc-sysbus.c
@@ -0,0 +1,252 @@ 
+/*
+ * QEMU Floppy disk emulator (Intel 82078)
+ *
+ * Copyright (c) 2003, 2007 Jocelyn Mayer
+ * Copyright (c) 2008 Hervé Poussineau
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qom/object.h"
+#include "hw/sysbus.h"
+#include "hw/block/fdc.h"
+#include "migration/vmstate.h"
+#include "fdc-internal.h"
+#include "trace.h"
+
+#define TYPE_SYSBUS_FDC "base-sysbus-fdc"
+typedef struct FDCtrlSysBusClass FDCtrlSysBusClass;
+typedef struct FDCtrlSysBus FDCtrlSysBus;
+DECLARE_OBJ_CHECKERS(FDCtrlSysBus, FDCtrlSysBusClass,
+                     SYSBUS_FDC, TYPE_SYSBUS_FDC)
+
+struct FDCtrlSysBusClass {
+    /*< private >*/
+    SysBusDeviceClass parent_class;
+    /*< public >*/
+
+    bool use_strict_io;
+};
+
+struct FDCtrlSysBus {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    struct FDCtrl state;
+};
+
+static uint64_t fdctrl_read_mem(void *opaque, hwaddr reg, unsigned ize)
+{
+    return fdctrl_read(opaque, (uint32_t)reg);
+}
+
+static void fdctrl_write_mem(void *opaque, hwaddr reg,
+                             uint64_t value, unsigned size)
+{
+    fdctrl_write(opaque, (uint32_t)reg, value);
+}
+
+static const MemoryRegionOps fdctrl_mem_ops = {
+    .read = fdctrl_read_mem,
+    .write = fdctrl_write_mem,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const MemoryRegionOps fdctrl_mem_strict_ops = {
+    .read = fdctrl_read_mem,
+    .write = fdctrl_write_mem,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
+static void fdctrl_external_reset_sysbus(DeviceState *d)
+{
+    FDCtrlSysBus *sys = SYSBUS_FDC(d);
+    FDCtrl *s = &sys->state;
+
+    fdctrl_reset(s, 0);
+}
+
+static void fdctrl_handle_tc(void *opaque, int irq, int level)
+{
+    trace_fdctrl_tc_pulse(level);
+}
+
+void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
+                        hwaddr mmio_base, DriveInfo **fds)
+{
+    FDCtrl *fdctrl;
+    DeviceState *dev;
+    SysBusDevice *sbd;
+    FDCtrlSysBus *sys;
+
+    dev = qdev_new("sysbus-fdc");
+    sys = SYSBUS_FDC(dev);
+    fdctrl = &sys->state;
+    fdctrl->dma_chann = dma_chann; /* FIXME */
+    sbd = SYS_BUS_DEVICE(dev);
+    sysbus_realize_and_unref(sbd, &error_fatal);
+    sysbus_connect_irq(sbd, 0, irq);
+    sysbus_mmio_map(sbd, 0, mmio_base);
+
+    fdctrl_init_drives(&sys->state.bus, fds);
+}
+
+void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
+                       DriveInfo **fds, qemu_irq *fdc_tc)
+{
+    DeviceState *dev;
+    FDCtrlSysBus *sys;
+
+    dev = qdev_new("sun-fdtwo");
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+    sys = SYSBUS_FDC(dev);
+    sysbus_connect_irq(SYS_BUS_DEVICE(sys), 0, irq);
+    sysbus_mmio_map(SYS_BUS_DEVICE(sys), 0, io_base);
+    *fdc_tc = qdev_get_gpio_in(dev, 0);
+
+    fdctrl_init_drives(&sys->state.bus, fds);
+}
+
+static void sysbus_fdc_common_initfn(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    FDCtrlSysBusClass *sbdc = SYSBUS_FDC_GET_CLASS(obj);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    FDCtrlSysBus *sys = SYSBUS_FDC(obj);
+    FDCtrl *fdctrl = &sys->state;
+
+    fdctrl->dma_chann = -1;
+
+    qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */
+
+    memory_region_init_io(&fdctrl->iomem, obj,
+                          sbdc->use_strict_io ? &fdctrl_mem_strict_ops
+                                              : &fdctrl_mem_ops,
+                          fdctrl, "fdc", 0x08);
+    sysbus_init_mmio(sbd, &fdctrl->iomem);
+
+    sysbus_init_irq(sbd, &fdctrl->irq);
+    qdev_init_gpio_in(dev, fdctrl_handle_tc, 1);
+}
+
+static void sysbus_fdc_common_realize(DeviceState *dev, Error **errp)
+{
+    FDCtrlSysBus *sys = SYSBUS_FDC(dev);
+    FDCtrl *fdctrl = &sys->state;
+
+    fdctrl_realize_common(dev, fdctrl, errp);
+}
+
+static const VMStateDescription vmstate_sysbus_fdc = {
+    .name = "fdc",
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .fields = (VMStateField[]) {
+        VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static Property sysbus_fdc_properties[] = {
+    DEFINE_PROP_SIGNED("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type,
+                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+                        FloppyDriveType),
+    DEFINE_PROP_SIGNED("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type,
+                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+                        FloppyDriveType),
+    DEFINE_PROP_SIGNED("fallback", FDCtrlSysBus, state.fallback,
+                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
+                        FloppyDriveType),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    device_class_set_props(dc, sysbus_fdc_properties);
+    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+}
+
+static const TypeInfo sysbus_fdc_info = {
+    .name          = "sysbus-fdc",
+    .parent        = TYPE_SYSBUS_FDC,
+    .class_init    = sysbus_fdc_class_init,
+};
+
+static void sysbus_fdc_common_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = sysbus_fdc_common_realize;
+    dc->reset = fdctrl_external_reset_sysbus;
+    dc->vmsd = &vmstate_sysbus_fdc;
+}
+
+static const TypeInfo sysbus_fdc_type_info = {
+    .name          = TYPE_SYSBUS_FDC,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(FDCtrlSysBus),
+    .instance_init = sysbus_fdc_common_initfn,
+    .abstract      = true,
+    .class_init    = sysbus_fdc_common_class_init,
+    .class_size    = sizeof(FDCtrlSysBusClass),
+};
+
+static Property sun4m_fdc_properties[] = {
+    DEFINE_PROP_SIGNED("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type,
+                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+                        FloppyDriveType),
+    DEFINE_PROP_SIGNED("fallback", FDCtrlSysBus, state.fallback,
+                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
+                        FloppyDriveType),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
+{
+    FDCtrlSysBusClass *sbdc = SYSBUS_FDC_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    sbdc->use_strict_io = true;
+    device_class_set_props(dc, sun4m_fdc_properties);
+    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+}
+
+static const TypeInfo sun4m_fdc_info = {
+    .name          = "sun-fdtwo",
+    .parent        = TYPE_SYSBUS_FDC,
+    .class_init    = sun4m_fdc_class_init,
+};
+
+static void sysbus_fdc_register_types(void)
+{
+    type_register_static(&sun4m_fdc_info);
+    type_register_static(&sysbus_fdc_type_info);
+    type_register_static(&sysbus_fdc_info);
+}
+
+type_init(sysbus_fdc_register_types)
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 50567d972ff..64af4d194ce 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -36,7 +36,6 @@ 
 #include "hw/isa/isa.h"
 #include "hw/qdev-properties.h"
 #include "hw/qdev-properties-system.h"
-#include "hw/sysbus.h"
 #include "migration/vmstate.h"
 #include "hw/block/block.h"
 #include "sysemu/block-backend.h"
@@ -775,17 +774,6 @@  static FloppyDriveType get_fallback_drive_type(FDrive *drv)
     return drv->fdctrl->fallback;
 }
 
-#define TYPE_SYSBUS_FDC "base-sysbus-fdc"
-OBJECT_DECLARE_SIMPLE_TYPE(FDCtrlSysBus, SYSBUS_FDC)
-
-struct FDCtrlSysBus {
-    /*< private >*/
-    SysBusDevice parent_obj;
-    /*< public >*/
-
-    struct FDCtrl state;
-};
-
 uint32_t fdctrl_read(void *opaque, uint32_t reg)
 {
     FDCtrl *fdctrl = opaque;
@@ -850,34 +838,6 @@  void fdctrl_write(void *opaque, uint32_t reg, uint32_t value)
     }
 }
 
-static uint64_t fdctrl_read_mem (void *opaque, hwaddr reg,
-                                 unsigned ize)
-{
-    return fdctrl_read(opaque, (uint32_t)reg);
-}
-
-static void fdctrl_write_mem (void *opaque, hwaddr reg,
-                              uint64_t value, unsigned size)
-{
-    fdctrl_write(opaque, (uint32_t)reg, value);
-}
-
-static const MemoryRegionOps fdctrl_mem_ops = {
-    .read = fdctrl_read_mem,
-    .write = fdctrl_write_mem,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const MemoryRegionOps fdctrl_mem_strict_ops = {
-    .read = fdctrl_read_mem,
-    .write = fdctrl_write_mem,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        .min_access_size = 1,
-        .max_access_size = 1,
-    },
-};
-
 static bool fdrive_media_changed_needed(void *opaque)
 {
     FDrive *drive = opaque;
@@ -1101,19 +1061,6 @@  const VMStateDescription vmstate_fdc = {
     }
 };
 
-static void fdctrl_external_reset_sysbus(DeviceState *d)
-{
-    FDCtrlSysBus *sys = SYSBUS_FDC(d);
-    FDCtrl *s = &sys->state;
-
-    fdctrl_reset(s, 0);
-}
-
-static void fdctrl_handle_tc(void *opaque, int irq, int level)
-{
-    trace_fdctrl_tc_pulse(level);
-}
-
 /* Change IRQ state */
 static void fdctrl_reset_irq(FDCtrl *fdctrl)
 {
@@ -2370,42 +2317,6 @@  void fdctrl_init_drives(FloppyBus *bus, DriveInfo **fds)
     }
 }
 
-void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
-                        hwaddr mmio_base, DriveInfo **fds)
-{
-    FDCtrl *fdctrl;
-    DeviceState *dev;
-    SysBusDevice *sbd;
-    FDCtrlSysBus *sys;
-
-    dev = qdev_new("sysbus-fdc");
-    sys = SYSBUS_FDC(dev);
-    fdctrl = &sys->state;
-    fdctrl->dma_chann = dma_chann; /* FIXME */
-    sbd = SYS_BUS_DEVICE(dev);
-    sysbus_realize_and_unref(sbd, &error_fatal);
-    sysbus_connect_irq(sbd, 0, irq);
-    sysbus_mmio_map(sbd, 0, mmio_base);
-
-    fdctrl_init_drives(&sys->state.bus, fds);
-}
-
-void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
-                       DriveInfo **fds, qemu_irq *fdc_tc)
-{
-    DeviceState *dev;
-    FDCtrlSysBus *sys;
-
-    dev = qdev_new("sun-fdtwo");
-    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
-    sys = SYSBUS_FDC(dev);
-    sysbus_connect_irq(SYS_BUS_DEVICE(sys), 0, irq);
-    sysbus_mmio_map(SYS_BUS_DEVICE(sys), 0, io_base);
-    *fdc_tc = qdev_get_gpio_in(dev, 0);
-
-    fdctrl_init_drives(&sys->state.bus, fds);
-}
-
 void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl, Error **errp)
 {
     int i, j;
@@ -2458,139 +2369,8 @@  void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl, Error **errp)
     }
 }
 
-static void sysbus_fdc_initfn(Object *obj)
-{
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-    FDCtrlSysBus *sys = SYSBUS_FDC(obj);
-    FDCtrl *fdctrl = &sys->state;
-
-    fdctrl->dma_chann = -1;
-
-    memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_ops, fdctrl,
-                          "fdc", 0x08);
-    sysbus_init_mmio(sbd, &fdctrl->iomem);
-}
-
-static void sun4m_fdc_initfn(Object *obj)
-{
-    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-    FDCtrlSysBus *sys = SYSBUS_FDC(obj);
-    FDCtrl *fdctrl = &sys->state;
-
-    fdctrl->dma_chann = -1;
-
-    memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_strict_ops,
-                          fdctrl, "fdctrl", 0x08);
-    sysbus_init_mmio(sbd, &fdctrl->iomem);
-}
-
-static void sysbus_fdc_common_initfn(Object *obj)
-{
-    DeviceState *dev = DEVICE(obj);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-    FDCtrlSysBus *sys = SYSBUS_FDC(obj);
-    FDCtrl *fdctrl = &sys->state;
-
-    qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */
-
-    sysbus_init_irq(sbd, &fdctrl->irq);
-    qdev_init_gpio_in(dev, fdctrl_handle_tc, 1);
-}
-
-static void sysbus_fdc_common_realize(DeviceState *dev, Error **errp)
-{
-    FDCtrlSysBus *sys = SYSBUS_FDC(dev);
-    FDCtrl *fdctrl = &sys->state;
-
-    fdctrl_realize_common(dev, fdctrl, errp);
-}
-
-static const VMStateDescription vmstate_sysbus_fdc ={
-    .name = "fdc",
-    .version_id = 2,
-    .minimum_version_id = 2,
-    .fields = (VMStateField[]) {
-        VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static Property sysbus_fdc_properties[] = {
-    DEFINE_PROP_SIGNED("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type,
-                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
-    DEFINE_PROP_SIGNED("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type,
-                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
-    DEFINE_PROP_SIGNED("fallback", FDCtrlSysBus, state.fallback,
-                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    device_class_set_props(dc, sysbus_fdc_properties);
-    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
-}
-
-static const TypeInfo sysbus_fdc_info = {
-    .name          = "sysbus-fdc",
-    .parent        = TYPE_SYSBUS_FDC,
-    .instance_init = sysbus_fdc_initfn,
-    .class_init    = sysbus_fdc_class_init,
-};
-
-static Property sun4m_fdc_properties[] = {
-    DEFINE_PROP_SIGNED("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type,
-                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
-    DEFINE_PROP_SIGNED("fallback", FDCtrlSysBus, state.fallback,
-                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    device_class_set_props(dc, sun4m_fdc_properties);
-    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
-}
-
-static const TypeInfo sun4m_fdc_info = {
-    .name          = "sun-fdtwo",
-    .parent        = TYPE_SYSBUS_FDC,
-    .instance_init = sun4m_fdc_initfn,
-    .class_init    = sun4m_fdc_class_init,
-};
-
-static void sysbus_fdc_common_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-
-    dc->realize = sysbus_fdc_common_realize;
-    dc->reset = fdctrl_external_reset_sysbus;
-    dc->vmsd = &vmstate_sysbus_fdc;
-}
-
-static const TypeInfo sysbus_fdc_type_info = {
-    .name          = TYPE_SYSBUS_FDC,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(FDCtrlSysBus),
-    .instance_init = sysbus_fdc_common_initfn,
-    .abstract      = true,
-    .class_init    = sysbus_fdc_common_class_init,
-};
-
 static void fdc_register_types(void)
 {
-    type_register_static(&sysbus_fdc_type_info);
-    type_register_static(&sysbus_fdc_info);
-    type_register_static(&sun4m_fdc_info);
     type_register_static(&floppy_bus_info);
     type_register_static(&floppy_drive_info);
 }
diff --git a/MAINTAINERS b/MAINTAINERS
index e7ed334f586..0a908c22103 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1678,6 +1678,7 @@  S: Supported
 F: hw/block/fdc.c
 F: hw/block/fdc-internal.h
 F: hw/block/fdc-isa.c
+F: hw/block/fdc-sysbus.c
 F: include/hw/block/fdc.h
 F: tests/qtest/fdc-test.c
 T: git https://gitlab.com/jsnow/qemu.git ide
diff --git a/hw/block/Kconfig b/hw/block/Kconfig
index 0a2c046fa6c..d50be837666 100644
--- a/hw/block/Kconfig
+++ b/hw/block/Kconfig
@@ -8,6 +8,10 @@  config FDC_ISA
     # select ISA_BUS here instead of polluting each board that requires one
     select ISA_BUS
 
+config FDC_SYSBUS
+    bool
+    select FDC
+
 config SSI_M25P80
     bool
 
diff --git a/hw/block/meson.build b/hw/block/meson.build
index f33a665c945..c3935350485 100644
--- a/hw/block/meson.build
+++ b/hw/block/meson.build
@@ -6,6 +6,7 @@ 
 softmmu_ss.add(when: 'CONFIG_ECC', if_true: files('ecc.c'))
 softmmu_ss.add(when: 'CONFIG_FDC', if_true: files('fdc.c'))
 softmmu_ss.add(when: 'CONFIG_FDC_ISA', if_true: files('fdc-isa.c'))
+softmmu_ss.add(when: 'CONFIG_FDC_SYSBUS', if_true: files('fdc-sysbus.c'))
 softmmu_ss.add(when: 'CONFIG_NAND', if_true: files('nand.c'))
 softmmu_ss.add(when: 'CONFIG_ONENAND', if_true: files('onenand.c'))
 softmmu_ss.add(when: 'CONFIG_PFLASH_CFI01', if_true: files('pflash_cfi01.c'))
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 306989c193c..266b34393a3 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -3,6 +3,8 @@ 
 # fdc.c
 fdc_ioport_read(uint8_t reg, uint8_t value) "read reg 0x%02x val 0x%02x"
 fdc_ioport_write(uint8_t reg, uint8_t value) "write reg 0x%02x val 0x%02x"
+
+# fdc-sysbus.c
 fdctrl_tc_pulse(int level) "TC pulse: %u"
 
 # pflash_cfi01.c
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index aadd436bf4e..c245e881a2b 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -20,7 +20,7 @@  config JAZZ
     select G364FB
     select DP8393X
     select ESP
-    select FDC
+    select FDC_SYSBUS
     select MC146818RTC
     select PCKBD
     select SERIAL
diff --git a/hw/sparc/Kconfig b/hw/sparc/Kconfig
index 8dcb10086fd..79d58beb7a6 100644
--- a/hw/sparc/Kconfig
+++ b/hw/sparc/Kconfig
@@ -8,7 +8,7 @@  config SUN4M
     select UNIMP
     select ESCC
     select ESP
-    select FDC
+    select FDC_SYSBUS
     select SLAVIO
     select LANCE
     select M48T59