/*
 * SPAPR machine hooks to Virtual Open Firmware,
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_vio.h"
#include "hw/ppc/spapr_cpu_core.h"
#include "hw/ppc/fdt.h"
#include "hw/ppc/vof.h"
#include "sysemu/sysemu.h"
#include "qom/qom-qobject.h"
#include "trace.h"

target_ulong spapr_h_vof_client(PowerPCCPU *cpu, SpaprMachineState *spapr,
                                target_ulong opcode, target_ulong *_args)
{
    int ret = vof_client_call(MACHINE(spapr), spapr->vof, spapr->fdt_blob,
                              ppc64_phys_to_real(_args[0]));

    if (ret) {
        return H_PARAMETER;
    }
    return H_SUCCESS;
}

void spapr_vof_client_dt_finalize(SpaprMachineState *spapr, void *fdt)
{
    g_autofree char *stdout_path = spapr_vio_stdout_path(spapr->vio_bus);

    vof_build_dt(fdt, spapr->vof);

    if (spapr->vof->bootargs) {
        int chosen;

        _FDT(chosen = fdt_path_offset(fdt, "/chosen"));
        /*
         * If the client did not change "bootargs", spapr_dt_chosen() must have
         * stored machine->kernel_cmdline in it before getting here.
         */
        _FDT(fdt_setprop_string(fdt, chosen, "bootargs", spapr->vof->bootargs));
    }

    /*
     * SLOF-less setup requires an open instance of stdout for early
     * kernel printk. By now all phandles are settled so we can open
     * the default serial console.
     */
    if (stdout_path) {
        _FDT(vof_client_open_store(fdt, spapr->vof, "/chosen", "stdout",
                                   stdout_path));
    }
}

void spapr_vof_reset(SpaprMachineState *spapr, void *fdt, Error **errp)
{
    target_ulong stack_ptr;
    Vof *vof = spapr->vof;
    PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);

    vof_init(vof, spapr->rma_size, errp);

    stack_ptr = vof_claim(vof, 0, VOF_STACK_SIZE, VOF_STACK_SIZE);
    if (stack_ptr == -1) {
        error_setg(errp, "Memory allocation for stack failed");
        return;
    }
    /* Stack grows downwards plus reserve space for the minimum stack frame */
    stack_ptr += VOF_STACK_SIZE - 0x20;

    if (spapr->kernel_size &&
        vof_claim(vof, spapr->kernel_addr, spapr->kernel_size, 0) == -1) {
        error_setg(errp, "Memory for kernel is in use");
        return;
    }

    if (spapr->initrd_size &&
        vof_claim(vof, spapr->initrd_base, spapr->initrd_size, 0) == -1) {
        error_setg(errp, "Memory for initramdisk is in use");
        return;
    }

    spapr_vof_client_dt_finalize(spapr, fdt);

    spapr_cpu_set_entry_state(first_ppc_cpu, SPAPR_ENTRY_POINT,
                              stack_ptr, spapr->initrd_base,
                              spapr->initrd_size);

    /*
     * At this point the expected allocation map is:
     *
     * 0..c38 - the initial firmware
     * 8000..10000 - stack
     * 400000.. - kernel
     * 3ea0000.. - initramdisk
     *
     * We skip writing FDT as nothing expects it; OF client interface is
     * going to be used for reading the device tree.
     */
}

void spapr_vof_quiesce(MachineState *ms)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(ms);

    spapr->fdt_size = fdt_totalsize(spapr->fdt_blob);
    spapr->fdt_initial_size = spapr->fdt_size;
}

bool spapr_vof_setprop(MachineState *ms, const char *path, const char *propname,
                       void *val, int vallen)
{
    SpaprMachineState *spapr = SPAPR_MACHINE(ms);

    /*
     * We only allow changing properties which we know how to update in QEMU
     * OR
     * the ones which we know that they need to survive during "quiesce".
     */

    if (strcmp(path, "/rtas") == 0) {
        if (strcmp(propname, "linux,rtas-base") == 0 ||
            strcmp(propname, "linux,rtas-entry") == 0) {
            /* These need to survive quiesce so let them store in the FDT */
            return true;
        }
    }

    if (strcmp(path, "/chosen") == 0) {
        if (strcmp(propname, "bootargs") == 0) {
            Vof *vof = spapr->vof;

            g_free(vof->bootargs);
            vof->bootargs = g_strndup(val, vallen);
            return true;
        }
        if (strcmp(propname, "linux,initrd-start") == 0) {
            if (vallen == sizeof(uint32_t)) {
                spapr->initrd_base = ldl_be_p(val);
                return true;
            }
            if (vallen == sizeof(uint64_t)) {
                spapr->initrd_base = ldq_be_p(val);
                return true;
            }
            return false;
        }
        if (strcmp(propname, "linux,initrd-end") == 0) {
            if (vallen == sizeof(uint32_t)) {
                spapr->initrd_size = ldl_be_p(val) - spapr->initrd_base;
                return true;
            }
            if (vallen == sizeof(uint64_t)) {
                spapr->initrd_size = ldq_be_p(val) - spapr->initrd_base;
                return true;
            }
            return false;
        }
    }

    return true;
}
