/*
 * Nios2 kernel loader
 *
 * Copyright (c) 2016 Marek Vasut <marek.vasut@gmail.com>
 *
 * Based on microblaze kernel loader
 *
 * Copyright (c) 2012 Peter Crosthwaite <peter.crosthwaite@petalogix.com>
 * Copyright (c) 2012 PetaLogix
 * Copyright (c) 2009 Edgar E. Iglesias.
 *
 * 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 "qemu/units.h"
#include "qemu/datadir.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "sysemu/device_tree.h"
#include "sysemu/reset.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "elf.h"

#include "boot.h"

#define NIOS2_MAGIC    0x534f494e

static struct nios2_boot_info {
    void (*machine_cpu_reset)(Nios2CPU *);
    uint32_t bootstrap_pc;
    uint32_t cmdline;
    uint32_t initrd_start;
    uint32_t initrd_end;
    uint32_t fdt;
} boot_info;

static void main_cpu_reset(void *opaque)
{
    Nios2CPU *cpu = opaque;
    CPUState *cs = CPU(cpu);
    CPUNios2State *env = &cpu->env;

    cpu_reset(CPU(cpu));

    env->regs[R_ARG0] = NIOS2_MAGIC;
    env->regs[R_ARG1] = boot_info.initrd_start;
    env->regs[R_ARG2] = boot_info.fdt;
    env->regs[R_ARG3] = boot_info.cmdline;

    cpu_set_pc(cs, boot_info.bootstrap_pc);
    if (boot_info.machine_cpu_reset) {
        boot_info.machine_cpu_reset(cpu);
    }
}

static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
{
    return addr - 0xc0000000LL;
}

static int nios2_load_dtb(struct nios2_boot_info bi, const uint32_t ramsize,
                          const char *kernel_cmdline, const char *dtb_filename)
{
    int fdt_size;
    void *fdt = NULL;
    int r;

    if (dtb_filename) {
        fdt = load_device_tree(dtb_filename, &fdt_size);
    }
    if (!fdt) {
        return 0;
    }

    if (kernel_cmdline) {
        r = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
                                    kernel_cmdline);
        if (r < 0) {
            fprintf(stderr, "couldn't set /chosen/bootargs\n");
        }
    }

    if (bi.initrd_start) {
        qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
                              translate_kernel_address(NULL, bi.initrd_start));

        qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
                              translate_kernel_address(NULL, bi.initrd_end));
    }

    cpu_physical_memory_write(bi.fdt, fdt, fdt_size);
    g_free(fdt);
    return fdt_size;
}

void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
                            uint32_t ramsize,
                            const char *initrd_filename,
                            const char *dtb_filename,
                            void (*machine_cpu_reset)(Nios2CPU *))
{
    const char *kernel_filename;
    const char *kernel_cmdline;
    const char *dtb_arg;
    char *filename = NULL;

    kernel_filename = current_machine->kernel_filename;
    kernel_cmdline = current_machine->kernel_cmdline;
    dtb_arg = current_machine->dtb;
    /* default to pcbios dtb as passed by machine_init */
    if (!dtb_arg) {
        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);
    }

    boot_info.machine_cpu_reset = machine_cpu_reset;
    qemu_register_reset(main_cpu_reset, cpu);

    if (kernel_filename) {
        int kernel_size, fdt_size;
        uint64_t entry, high;
        int big_endian = 0;

#if TARGET_BIG_ENDIAN
        big_endian = 1;
#endif

        /* Boots a kernel elf binary. */
        kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
                               &entry, NULL, &high, NULL,
                               big_endian, EM_ALTERA_NIOS2, 0, 0);
        if ((uint32_t)entry == 0xc0000000) {
            /*
             * The Nios II processor reference guide documents that the
             * kernel is placed at virtual memory address 0xc0000000,
             * and we've got something that points there.  Reload it
             * and adjust the entry to get the address in physical RAM.
             */
            kernel_size = load_elf(kernel_filename, NULL,
                                   translate_kernel_address, NULL,
                                   &entry, NULL, NULL, NULL,
                                   big_endian, EM_ALTERA_NIOS2, 0, 0);
            boot_info.bootstrap_pc = ddr_base + 0xc0000000 +
                (entry & 0x07ffffff);
        } else {
            /* Use the entry point in the ELF image.  */
            boot_info.bootstrap_pc = (uint32_t)entry;
        }

        /* If it wasn't an ELF image, try an u-boot image. */
        if (kernel_size < 0) {
            hwaddr uentry, loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;

            kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
                                      NULL, NULL);
            boot_info.bootstrap_pc = uentry;
            high = loadaddr + kernel_size;
        }

        /* Not an ELF image nor an u-boot image, try a RAW image. */
        if (kernel_size < 0) {
            kernel_size = load_image_targphys(kernel_filename, ddr_base,
                                              ramsize);
            boot_info.bootstrap_pc = ddr_base;
            high = ddr_base + kernel_size;
        }

        high = ROUND_UP(high, 1 * MiB);

        /* If initrd is available, it goes after the kernel, aligned to 1M. */
        if (initrd_filename) {
            int initrd_size;
            uint32_t initrd_offset;

            boot_info.initrd_start = high;
            initrd_offset = boot_info.initrd_start - ddr_base;

            initrd_size = load_ramdisk(initrd_filename,
                                       boot_info.initrd_start,
                                       ramsize - initrd_offset);
            if (initrd_size < 0) {
                initrd_size = load_image_targphys(initrd_filename,
                                                  boot_info.initrd_start,
                                                  ramsize - initrd_offset);
            }
            if (initrd_size < 0) {
                error_report("could not load initrd '%s'",
                             initrd_filename);
                exit(EXIT_FAILURE);
            }
            high += initrd_size;
        }
        high = ROUND_UP(high, 4);
        boot_info.initrd_end = high;

        /* Device tree must be placed right after initrd (if available) */
        boot_info.fdt = high;
        fdt_size = nios2_load_dtb(boot_info, ramsize, kernel_cmdline,
                                  /* Preference a -dtb argument */
                                  dtb_arg ? dtb_arg : filename);
        high += fdt_size;

        /* Kernel command is at the end, 4k aligned. */
        boot_info.cmdline = ROUND_UP(high, 4 * KiB);
        if (kernel_cmdline && strlen(kernel_cmdline)) {
            pstrcpy_targphys("cmdline", boot_info.cmdline, 256, kernel_cmdline);
        }
    }
    g_free(filename);
}
