/*
 * 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.
 */
/*
 * The controller is used in Sun4m systems in a slightly different
 * way. There are changes in DOR register and DMA is not available.
 */

#include "qemu/osdep.h"
#include "hw/block/fdc.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/timer.h"
#include "hw/acpi/acpi_aml_interface.h"
#include "hw/irq.h"
#include "hw/isa/isa.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "migration/vmstate.h"
#include "hw/block/block.h"
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "sysemu/sysemu.h"
#include "exec/ioport.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "trace.h"
#include "qom/object.h"
#include "fdc-internal.h"

OBJECT_DECLARE_SIMPLE_TYPE(FDCtrlISABus, ISA_FDC)

struct FDCtrlISABus {
    /*< private >*/
    ISADevice parent_obj;
    /*< public >*/

    uint32_t iobase;
    uint32_t irq;
    uint32_t dma;
    struct FDCtrl state;
    PortioList portio_list;
    int32_t bootindexA;
    int32_t bootindexB;
};

static void fdctrl_external_reset_isa(DeviceState *d)
{
    FDCtrlISABus *isa = ISA_FDC(d);
    FDCtrl *s = &isa->state;

    fdctrl_reset(s, 0);
}

void isa_fdc_init_drives(ISADevice *fdc, DriveInfo **fds)
{
    fdctrl_init_drives(&ISA_FDC(fdc)->state.bus, fds);
}

static const MemoryRegionPortio fdc_portio_list[] = {
    { 1, 5, 1, .read = fdctrl_read, .write = fdctrl_write },
    { 7, 1, 1, .read = fdctrl_read, .write = fdctrl_write },
    PORTIO_END_OF_LIST(),
};

static void isabus_fdc_realize(DeviceState *dev, Error **errp)
{
    ISADevice *isadev = ISA_DEVICE(dev);
    ISABus *bus = isa_bus_from_device(isadev);
    FDCtrlISABus *isa = ISA_FDC(dev);
    FDCtrl *fdctrl = &isa->state;
    Error *err = NULL;

    isa_register_portio_list(isadev, &isa->portio_list,
                             isa->iobase, fdc_portio_list, fdctrl,
                             "fdc");

    fdctrl->irq = isa_bus_get_irq(bus, isa->irq);
    fdctrl->dma_chann = isa->dma;
    if (fdctrl->dma_chann != -1) {
        IsaDmaClass *k;
        fdctrl->dma = isa_bus_get_dma(bus, isa->dma);
        if (!fdctrl->dma) {
            error_setg(errp, "ISA controller does not support DMA");
            return;
        }
        k = ISADMA_GET_CLASS(fdctrl->dma);
        k->register_channel(fdctrl->dma, fdctrl->dma_chann,
                            &fdctrl_transfer_handler, fdctrl);
    }

    qdev_set_legacy_instance_id(dev, isa->iobase, 2);

    fdctrl_realize_common(dev, fdctrl, &err);
    if (err != NULL) {
        error_propagate(errp, err);
        return;
    }
}

FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
{
    FDCtrlISABus *isa = ISA_FDC(fdc);

    return isa->state.drives[i].drive;
}

static void isa_fdc_get_drive_max_chs(FloppyDriveType type, uint8_t *maxc,
                                      uint8_t *maxh, uint8_t *maxs)
{
    const FDFormat *fdf;

    *maxc = *maxh = *maxs = 0;
    for (fdf = fd_formats; fdf->drive != FLOPPY_DRIVE_TYPE_NONE; fdf++) {
        if (fdf->drive != type) {
            continue;
        }
        if (*maxc < fdf->max_track) {
            *maxc = fdf->max_track;
        }
        if (*maxh < fdf->max_head) {
            *maxh = fdf->max_head;
        }
        if (*maxs < fdf->last_sect) {
            *maxs = fdf->last_sect;
        }
    }
    (*maxc)--;
}

static Aml *build_fdinfo_aml(int idx, FloppyDriveType type)
{
    Aml *dev, *fdi;
    uint8_t maxc, maxh, maxs;

    isa_fdc_get_drive_max_chs(type, &maxc, &maxh, &maxs);

    dev = aml_device("FLP%c", 'A' + idx);

    aml_append(dev, aml_name_decl("_ADR", aml_int(idx)));

    fdi = aml_package(16);
    aml_append(fdi, aml_int(idx));  /* Drive Number */
    aml_append(fdi,
        aml_int(cmos_get_fd_drive_type(type)));  /* Device Type */
    /*
     * the values below are the limits of the drive, and are thus independent
     * of the inserted media
     */
    aml_append(fdi, aml_int(maxc));  /* Maximum Cylinder Number */
    aml_append(fdi, aml_int(maxs));  /* Maximum Sector Number */
    aml_append(fdi, aml_int(maxh));  /* Maximum Head Number */
    /*
     * SeaBIOS returns the below values for int 0x13 func 0x08 regardless of
     * the drive type, so shall we
     */
    aml_append(fdi, aml_int(0xAF));  /* disk_specify_1 */
    aml_append(fdi, aml_int(0x02));  /* disk_specify_2 */
    aml_append(fdi, aml_int(0x25));  /* disk_motor_wait */
    aml_append(fdi, aml_int(0x02));  /* disk_sector_siz */
    aml_append(fdi, aml_int(0x12));  /* disk_eot */
    aml_append(fdi, aml_int(0x1B));  /* disk_rw_gap */
    aml_append(fdi, aml_int(0xFF));  /* disk_dtl */
    aml_append(fdi, aml_int(0x6C));  /* disk_formt_gap */
    aml_append(fdi, aml_int(0xF6));  /* disk_fill */
    aml_append(fdi, aml_int(0x0F));  /* disk_head_sttl */
    aml_append(fdi, aml_int(0x08));  /* disk_motor_strt */

    aml_append(dev, aml_name_decl("_FDI", fdi));
    return dev;
}

void isa_fdc_set_iobase(ISADevice *fdc, hwaddr iobase)
{
    FDCtrlISABus *isa = ISA_FDC(fdc);

    fdc->ioport_id = iobase;
    isa->iobase = iobase;
    portio_list_set_address(&isa->portio_list, isa->iobase);
}

void isa_fdc_set_enabled(ISADevice *fdc, bool enabled)
{
    portio_list_set_enabled(&ISA_FDC(fdc)->portio_list, enabled);
}

int cmos_get_fd_drive_type(FloppyDriveType fd0)
{
    int val;

    switch (fd0) {
    case FLOPPY_DRIVE_TYPE_144:
        /* 1.44 Mb 3"5 drive */
        val = 4;
        break;
    case FLOPPY_DRIVE_TYPE_288:
        /* 2.88 Mb 3"5 drive */
        val = 5;
        break;
    case FLOPPY_DRIVE_TYPE_120:
        /* 1.2 Mb 5"5 drive */
        val = 2;
        break;
    case FLOPPY_DRIVE_TYPE_NONE:
    default:
        val = 0;
        break;
    }
    return val;
}

static void build_fdc_aml(AcpiDevAmlIf *adev, Aml *scope)
{
    FDCtrlISABus *isa = ISA_FDC(adev);
    Aml *dev;
    Aml *crs;
    int i;

#define ACPI_FDE_MAX_FD 4
    uint32_t fde_buf[5] = {
        0, 0, 0, 0,     /* presence of floppy drives #0 - #3 */
        cpu_to_le32(2)  /* tape presence (2 == never present) */
    };

    crs = aml_resource_template();
    aml_append(crs,
        aml_io(AML_DECODE16, isa->iobase + 2, isa->iobase + 2, 0x00, 0x04));
    aml_append(crs,
        aml_io(AML_DECODE16, isa->iobase + 7, isa->iobase + 7, 0x00, 0x01));
    aml_append(crs, aml_irq_no_flags(isa->irq));
    aml_append(crs,
        aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, isa->dma));

    dev = aml_device("FDC0");
    aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0700")));
    aml_append(dev, aml_name_decl("_CRS", crs));

    for (i = 0; i < MIN(MAX_FD, ACPI_FDE_MAX_FD); i++) {
        FloppyDriveType type = isa_fdc_get_drive_type(ISA_DEVICE(adev), i);

        if (type < FLOPPY_DRIVE_TYPE_NONE) {
            fde_buf[i] = cpu_to_le32(1);  /* drive present */
            aml_append(dev, build_fdinfo_aml(i, type));
        }
    }
    aml_append(dev, aml_name_decl("_FDE",
               aml_buffer(sizeof(fde_buf), (uint8_t *)fde_buf)));

    aml_append(scope, dev);
}

static const VMStateDescription vmstate_isa_fdc = {
    .name = "fdc",
    .version_id = 2,
    .minimum_version_id = 2,
    .fields = (const VMStateField[]) {
        VMSTATE_STRUCT(state, FDCtrlISABus, 0, vmstate_fdc, FDCtrl),
        VMSTATE_END_OF_LIST()
    }
};

static Property isa_fdc_properties[] = {
    DEFINE_PROP_UINT32("iobase", FDCtrlISABus, iobase, 0x3f0),
    DEFINE_PROP_UINT32("irq", FDCtrlISABus, irq, 6),
    DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
    DEFINE_PROP_SIGNED("fdtypeA", FDCtrlISABus, state.qdev_for_drives[0].type,
                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
                        FloppyDriveType),
    DEFINE_PROP_SIGNED("fdtypeB", FDCtrlISABus, state.qdev_for_drives[1].type,
                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
                        FloppyDriveType),
    DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback,
                        FLOPPY_DRIVE_TYPE_288, qdev_prop_fdc_drive_type,
                        FloppyDriveType),
    DEFINE_PROP_END_OF_LIST(),
};

static void isabus_fdc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);

    dc->desc = "virtual floppy controller";
    dc->realize = isabus_fdc_realize;
    dc->fw_name = "fdc";
    dc->reset = fdctrl_external_reset_isa;
    dc->vmsd = &vmstate_isa_fdc;
    adevc->build_dev_aml = build_fdc_aml;
    device_class_set_props(dc, isa_fdc_properties);
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}

static void isabus_fdc_instance_init(Object *obj)
{
    FDCtrlISABus *isa = ISA_FDC(obj);

    device_add_bootindex_property(obj, &isa->bootindexA,
                                  "bootindexA", "/floppy@0",
                                  DEVICE(obj));
    device_add_bootindex_property(obj, &isa->bootindexB,
                                  "bootindexB", "/floppy@1",
                                  DEVICE(obj));
}

static const TypeInfo isa_fdc_info = {
    .name          = TYPE_ISA_FDC,
    .parent        = TYPE_ISA_DEVICE,
    .instance_size = sizeof(FDCtrlISABus),
    .class_init    = isabus_fdc_class_init,
    .instance_init = isabus_fdc_instance_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_ACPI_DEV_AML_IF },
        { },
    },
};

static void isa_fdc_register_types(void)
{
    type_register_static(&isa_fdc_info);
}

type_init(isa_fdc_register_types)
