/*
 * QEMU model of the Canon DIGIC boards (cameras indeed :).
 *
 * Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
 *
 * This model is based on reverse engineering efforts
 * made by CHDK (http://chdk.wikia.com) and
 * Magic Lantern (http://www.magiclantern.fm) projects
 * contributors.
 *
 * See docs here:
 *   http://magiclantern.wikia.com/wiki/Register_Map
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "cpu.h"
#include "hw/boards.h"
#include "exec/address-spaces.h"
#include "qemu/error-report.h"
#include "hw/arm/digic.h"
#include "hw/block/flash.h"
#include "hw/loader.h"
#include "sysemu/sysemu.h"
#include "sysemu/qtest.h"

#define DIGIC4_ROM0_BASE      0xf0000000
#define DIGIC4_ROM1_BASE      0xf8000000
#define DIGIC4_ROM_MAX_SIZE   0x08000000

typedef struct DigicBoardState {
    DigicState *digic;
    MemoryRegion ram;
} DigicBoardState;

typedef struct DigicBoard {
    hwaddr ram_size;
    void (*add_rom0)(DigicBoardState *, hwaddr, const char *);
    const char *rom0_def_filename;
    void (*add_rom1)(DigicBoardState *, hwaddr, const char *);
    const char *rom1_def_filename;
} DigicBoard;

static void digic4_board_setup_ram(DigicBoardState *s, hwaddr ram_size)
{
    memory_region_allocate_system_memory(&s->ram, NULL, "ram", ram_size);
    memory_region_add_subregion(get_system_memory(), 0, &s->ram);
}

static void digic4_board_init(DigicBoard *board)
{
    Error *err = NULL;

    DigicBoardState *s = g_new(DigicBoardState, 1);

    s->digic = DIGIC(object_new(TYPE_DIGIC));
    object_property_set_bool(OBJECT(s->digic), true, "realized", &err);
    if (err != NULL) {
        error_reportf_err(err, "Couldn't realize DIGIC SoC: ");
        exit(1);
    }

    digic4_board_setup_ram(s, board->ram_size);

    if (board->add_rom0) {
        board->add_rom0(s, DIGIC4_ROM0_BASE, board->rom0_def_filename);
    }

    if (board->add_rom1) {
        board->add_rom1(s, DIGIC4_ROM1_BASE, board->rom1_def_filename);
    }
}

static void digic_load_rom(DigicBoardState *s, hwaddr addr,
                           hwaddr max_size, const char *def_filename)
{
    target_long rom_size;
    const char *filename;

    if (qtest_enabled()) {
        /* qtest runs no code so don't attempt a ROM load which
         * could fail and result in a spurious test failure.
         */
        return;
    }

    if (bios_name) {
        filename = bios_name;
    } else {
        filename = def_filename;
    }

    if (filename) {
        char *fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);

        if (!fn) {
            error_report("Couldn't find rom image '%s'.", filename);
            exit(1);
        }

        rom_size = load_image_targphys(fn, addr, max_size);
        if (rom_size < 0 || rom_size > max_size) {
            error_report("Couldn't load rom image '%s'.", filename);
            exit(1);
        }
        g_free(fn);
    }
}

/*
 * Samsung K8P3215UQB
 * 64M Bit (4Mx16) Page Mode / Multi-Bank NOR Flash Memory
 */
static void digic4_add_k8p3215uqb_rom(DigicBoardState *s, hwaddr addr,
                                      const char *def_filename)
{
#define FLASH_K8P3215UQB_SIZE (4 * 1024 * 1024)
#define FLASH_K8P3215UQB_SECTOR_SIZE (64 * 1024)

    pflash_cfi02_register(addr, NULL, "pflash", FLASH_K8P3215UQB_SIZE,
                          NULL, FLASH_K8P3215UQB_SECTOR_SIZE,
                          FLASH_K8P3215UQB_SIZE / FLASH_K8P3215UQB_SECTOR_SIZE,
                          DIGIC4_ROM_MAX_SIZE / FLASH_K8P3215UQB_SIZE,
                          4,
                          0x00EC, 0x007E, 0x0003, 0x0001,
                          0x0555, 0x2aa, 0);

    digic_load_rom(s, addr, FLASH_K8P3215UQB_SIZE, def_filename);
}

static DigicBoard digic4_board_canon_a1100 = {
    .ram_size = 64 * 1024 * 1024,
    .add_rom1 = digic4_add_k8p3215uqb_rom,
    .rom1_def_filename = "canon-a1100-rom1.bin",
};

static void canon_a1100_init(MachineState *machine)
{
    digic4_board_init(&digic4_board_canon_a1100);
}

static void canon_a1100_machine_init(MachineClass *mc)
{
    mc->desc = "Canon PowerShot A1100 IS";
    mc->init = &canon_a1100_init;
}

DEFINE_MACHINE("canon-a1100", canon_a1100_machine_init)
