/*
 * QEMU Arduino boards
 *
 * Copyright (c) 2019-2020 Philippe Mathieu-Daudé
 *
 * This work is licensed under the terms of the GNU GPLv2 or later.
 * See the COPYING file in the top-level directory.
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

/* TODO: Implement the use of EXTRAM */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/boards.h"
#include "atmega.h"
#include "boot.h"
#include "qom/object.h"

struct ArduinoMachineState {
    /*< private >*/
    MachineState parent_obj;
    /*< public >*/
    AtmegaMcuState mcu;
};
typedef struct ArduinoMachineState ArduinoMachineState;

struct ArduinoMachineClass {
    /*< private >*/
    MachineClass parent_class;
    /*< public >*/
    const char *mcu_type;
    uint64_t xtal_hz;
};
typedef struct ArduinoMachineClass ArduinoMachineClass;

#define TYPE_ARDUINO_MACHINE \
        MACHINE_TYPE_NAME("arduino")
DECLARE_OBJ_CHECKERS(ArduinoMachineState, ArduinoMachineClass,
                     ARDUINO_MACHINE, TYPE_ARDUINO_MACHINE)

static void arduino_machine_init(MachineState *machine)
{
    ArduinoMachineClass *amc = ARDUINO_MACHINE_GET_CLASS(machine);
    ArduinoMachineState *ams = ARDUINO_MACHINE(machine);

    object_initialize_child(OBJECT(machine), "mcu", &ams->mcu, amc->mcu_type);
    object_property_set_uint(OBJECT(&ams->mcu), "xtal-frequency-hz",
                             amc->xtal_hz, &error_abort);
    sysbus_realize(SYS_BUS_DEVICE(&ams->mcu), &error_abort);

    if (machine->firmware) {
        if (!avr_load_firmware(&ams->mcu.cpu, machine,
                               &ams->mcu.flash, machine->firmware)) {
            exit(1);
        }
    }
}

static void arduino_machine_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);

    mc->init = arduino_machine_init;
    mc->default_cpus = 1;
    mc->min_cpus = mc->default_cpus;
    mc->max_cpus = mc->default_cpus;
    mc->no_floppy = 1;
    mc->no_cdrom = 1;
    mc->no_parallel = 1;
}

static void arduino_duemilanove_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);
    ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);

    /*
     * https://www.arduino.cc/en/Main/ArduinoBoardDuemilanove
     * https://www.arduino.cc/en/uploads/Main/arduino-duemilanove-schematic.pdf
     */
    mc->desc        = "Arduino Duemilanove (ATmega168)",
    mc->alias       = "2009";
    amc->mcu_type   = TYPE_ATMEGA168_MCU;
    amc->xtal_hz    = 16 * 1000 * 1000;
};

static void arduino_uno_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);
    ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);

    /*
     * https://store.arduino.cc/arduino-uno-rev3
     * https://www.arduino.cc/en/uploads/Main/arduino-uno-schematic.pdf
     */
    mc->desc        = "Arduino UNO (ATmega328P)";
    mc->alias       = "uno";
    amc->mcu_type   = TYPE_ATMEGA328_MCU;
    amc->xtal_hz    = 16 * 1000 * 1000;
};

static void arduino_mega_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);
    ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);

    /*
     * https://www.arduino.cc/en/Main/ArduinoBoardMega
     * https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf
     */
    mc->desc        = "Arduino Mega (ATmega1280)";
    mc->alias       = "mega";
    amc->mcu_type   = TYPE_ATMEGA1280_MCU;
    amc->xtal_hz    = 16 * 1000 * 1000;
};

static void arduino_mega2560_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);
    ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);

    /*
     * https://store.arduino.cc/arduino-mega-2560-rev3
     * https://www.arduino.cc/en/uploads/Main/arduino-mega2560_R3-sch.pdf
     */
    mc->desc        = "Arduino Mega 2560 (ATmega2560)";
    mc->alias       = "mega2560";
    amc->mcu_type   = TYPE_ATMEGA2560_MCU;
    amc->xtal_hz    = 16 * 1000 * 1000; /* CSTCE16M0V53-R0 */
};

static const TypeInfo arduino_machine_types[] = {
    {
        .name          = MACHINE_TYPE_NAME("arduino-duemilanove"),
        .parent        = TYPE_ARDUINO_MACHINE,
        .class_init    = arduino_duemilanove_class_init,
    }, {
        .name          = MACHINE_TYPE_NAME("arduino-uno"),
        .parent        = TYPE_ARDUINO_MACHINE,
        .class_init    = arduino_uno_class_init,
    }, {
        .name          = MACHINE_TYPE_NAME("arduino-mega"),
        .parent        = TYPE_ARDUINO_MACHINE,
        .class_init    = arduino_mega_class_init,
    }, {
        .name          = MACHINE_TYPE_NAME("arduino-mega-2560-v3"),
        .parent        = TYPE_ARDUINO_MACHINE,
        .class_init    = arduino_mega2560_class_init,
    }, {
        .name           = TYPE_ARDUINO_MACHINE,
        .parent         = TYPE_MACHINE,
        .instance_size  = sizeof(ArduinoMachineState),
        .class_size     = sizeof(ArduinoMachineClass),
        .class_init     = arduino_machine_class_init,
        .abstract       = true,
    }
};

DEFINE_TYPES(arduino_machine_types)
