/*
 * QEMU Machine core (related to -smp parsing)
 *
 * Copyright (c) 2021 Huawei Technologies Co., Ltd
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "hw/boards.h"
#include "qapi/error.h"
#include "qemu/error-report.h"


/*
 * Report information of a machine's supported CPU topology hierarchy.
 * Topology members will be ordered from the largest to the smallest
 * in the string.
 */
static char *cpu_hierarchy_to_string(MachineState *ms)
{
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    GString *s = g_string_new(NULL);

    if (mc->smp_props.drawers_supported) {
        g_string_append_printf(s, "drawers (%u) * ", ms->smp.drawers);
    }

    if (mc->smp_props.books_supported) {
        g_string_append_printf(s, "books (%u) * ", ms->smp.books);
    }

    g_string_append_printf(s, "sockets (%u)", ms->smp.sockets);

    if (mc->smp_props.dies_supported) {
        g_string_append_printf(s, " * dies (%u)", ms->smp.dies);
    }

    if (mc->smp_props.clusters_supported) {
        g_string_append_printf(s, " * clusters (%u)", ms->smp.clusters);
    }

    if (mc->smp_props.modules_supported) {
        g_string_append_printf(s, " * modules (%u)", ms->smp.modules);
    }

    g_string_append_printf(s, " * cores (%u)", ms->smp.cores);
    g_string_append_printf(s, " * threads (%u)", ms->smp.threads);

    return g_string_free(s, false);
}

/*
 * machine_parse_smp_config: Generic function used to parse the given
 *                           SMP configuration
 *
 * Any missing parameter in "cpus/maxcpus/sockets/cores/threads" will be
 * automatically computed based on the provided ones.
 *
 * In the calculation of omitted sockets/cores/threads: we prefer sockets
 * over cores over threads before 6.2, while preferring cores over sockets
 * over threads since 6.2.
 *
 * In the calculation of cpus/maxcpus: When both maxcpus and cpus are omitted,
 * maxcpus will be computed from the given parameters and cpus will be set
 * equal to maxcpus. When only one of maxcpus and cpus is given then the
 * omitted one will be set to its given counterpart's value. Both maxcpus and
 * cpus may be specified, but maxcpus must be equal to or greater than cpus.
 *
 * For compatibility, apart from the parameters that will be computed, newly
 * introduced topology members which are likely to be target specific should
 * be directly set as 1 if they are omitted (e.g. dies for PC since 4.1).
 */
void machine_parse_smp_config(MachineState *ms,
                              const SMPConfiguration *config, Error **errp)
{
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    unsigned cpus    = config->has_cpus ? config->cpus : 0;
    unsigned drawers = config->has_drawers ? config->drawers : 0;
    unsigned books   = config->has_books ? config->books : 0;
    unsigned sockets = config->has_sockets ? config->sockets : 0;
    unsigned dies    = config->has_dies ? config->dies : 0;
    unsigned clusters = config->has_clusters ? config->clusters : 0;
    unsigned modules = config->has_modules ? config->modules : 0;
    unsigned cores   = config->has_cores ? config->cores : 0;
    unsigned threads = config->has_threads ? config->threads : 0;
    unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
    unsigned total_cpus;

    /*
     * Specified CPU topology parameters must be greater than zero,
     * explicit configuration like "cpus=0" is not allowed.
     */
    if ((config->has_cpus && config->cpus == 0) ||
        (config->has_drawers && config->drawers == 0) ||
        (config->has_books && config->books == 0) ||
        (config->has_sockets && config->sockets == 0) ||
        (config->has_dies && config->dies == 0) ||
        (config->has_clusters && config->clusters == 0) ||
        (config->has_modules && config->modules == 0) ||
        (config->has_cores && config->cores == 0) ||
        (config->has_threads && config->threads == 0) ||
        (config->has_maxcpus && config->maxcpus == 0)) {
        error_setg(errp, "Invalid CPU topology: "
                   "CPU topology parameters must be greater than zero");
        return;
    }

    /*
     * If not supported by the machine, a topology parameter must
     * not be set to a value greater than 1.
     */
    if (!mc->smp_props.modules_supported &&
        config->has_modules && config->modules > 1) {
        error_setg(errp,
                   "modules > 1 not supported by this machine's CPU topology");
        return;
    }
    modules = modules > 0 ? modules : 1;

    if (!mc->smp_props.clusters_supported &&
        config->has_clusters && config->clusters > 1) {
        error_setg(errp,
                   "clusters > 1 not supported by this machine's CPU topology");
        return;
    }
    clusters = clusters > 0 ? clusters : 1;

    if (!mc->smp_props.dies_supported &&
        config->has_dies && config->dies > 1) {
        error_setg(errp,
                   "dies > 1 not supported by this machine's CPU topology");
        return;
    }
    dies = dies > 0 ? dies : 1;

    if (!mc->smp_props.books_supported &&
        config->has_books && config->books > 1) {
        error_setg(errp,
                   "books > 1 not supported by this machine's CPU topology");
        return;
    }
    books = books > 0 ? books : 1;

    if (!mc->smp_props.drawers_supported &&
        config->has_drawers && config->drawers > 1) {
        error_setg(errp,
                   "drawers > 1 not supported by this machine's CPU topology");
        return;
    }
    drawers = drawers > 0 ? drawers : 1;

    /* compute missing values based on the provided ones */
    if (cpus == 0 && maxcpus == 0) {
        sockets = sockets > 0 ? sockets : 1;
        cores = cores > 0 ? cores : 1;
        threads = threads > 0 ? threads : 1;
    } else {
        maxcpus = maxcpus > 0 ? maxcpus : cpus;

        if (mc->smp_props.prefer_sockets) {
            /* prefer sockets over cores before 6.2 */
            if (sockets == 0) {
                cores = cores > 0 ? cores : 1;
                threads = threads > 0 ? threads : 1;
                sockets = maxcpus /
                          (drawers * books * dies * clusters *
                           modules * cores * threads);
            } else if (cores == 0) {
                threads = threads > 0 ? threads : 1;
                cores = maxcpus /
                        (drawers * books * sockets * dies *
                         clusters * modules * threads);
            }
        } else {
            /* prefer cores over sockets since 6.2 */
            if (cores == 0) {
                sockets = sockets > 0 ? sockets : 1;
                threads = threads > 0 ? threads : 1;
                cores = maxcpus /
                        (drawers * books * sockets * dies *
                         clusters * modules * threads);
            } else if (sockets == 0) {
                threads = threads > 0 ? threads : 1;
                sockets = maxcpus /
                          (drawers * books * dies * clusters *
                           modules * cores * threads);
            }
        }

        /* try to calculate omitted threads at last */
        if (threads == 0) {
            threads = maxcpus /
                      (drawers * books * sockets * dies *
                       clusters * modules * cores);
        }
    }

    total_cpus = drawers * books * sockets * dies *
                 clusters * modules * cores * threads;
    maxcpus = maxcpus > 0 ? maxcpus : total_cpus;
    cpus = cpus > 0 ? cpus : maxcpus;

    ms->smp.cpus = cpus;
    ms->smp.drawers = drawers;
    ms->smp.books = books;
    ms->smp.sockets = sockets;
    ms->smp.dies = dies;
    ms->smp.clusters = clusters;
    ms->smp.modules = modules;
    ms->smp.cores = cores;
    ms->smp.threads = threads;
    ms->smp.max_cpus = maxcpus;

    mc->smp_props.has_clusters = config->has_clusters;

    /* sanity-check of the computed topology */
    if (total_cpus != maxcpus) {
        g_autofree char *topo_msg = cpu_hierarchy_to_string(ms);
        error_setg(errp, "Invalid CPU topology: "
                   "product of the hierarchy must match maxcpus: "
                   "%s != maxcpus (%u)",
                   topo_msg, maxcpus);
        return;
    }

    if (maxcpus < cpus) {
        g_autofree char *topo_msg = cpu_hierarchy_to_string(ms);
        error_setg(errp, "Invalid CPU topology: "
                   "maxcpus must be equal to or greater than smp: "
                   "%s == maxcpus (%u) < smp_cpus (%u)",
                   topo_msg, maxcpus, cpus);
        return;
    }

    if (ms->smp.cpus < mc->min_cpus) {
        error_setg(errp, "Invalid SMP CPUs %d. The min CPUs "
                   "supported by machine '%s' is %d",
                   ms->smp.cpus,
                   mc->name, mc->min_cpus);
        return;
    }

    if (ms->smp.max_cpus > mc->max_cpus) {
        error_setg(errp, "Invalid SMP CPUs %d. The max CPUs "
                   "supported by machine '%s' is %d",
                   ms->smp.max_cpus,
                   mc->name, mc->max_cpus);
        return;
    }
}

bool machine_parse_smp_cache(MachineState *ms,
                             const SmpCachePropertiesList *caches,
                             Error **errp)
{
    const SmpCachePropertiesList *node;
    DECLARE_BITMAP(caches_bitmap, CACHE_LEVEL_AND_TYPE__MAX);

    for (node = caches; node; node = node->next) {
        /* Prohibit users from repeating settings. */
        if (test_bit(node->value->cache, caches_bitmap)) {
            error_setg(errp,
                       "Invalid cache properties: %s. "
                       "The cache properties are duplicated",
                       CacheLevelAndType_str(node->value->cache));
            return false;
        }

        machine_set_cache_topo_level(ms, node->value->cache,
                                     node->value->topology);
        set_bit(node->value->cache, caches_bitmap);
    }

    return true;
}

unsigned int machine_topo_get_cores_per_socket(const MachineState *ms)
{
    return ms->smp.cores * ms->smp.modules * ms->smp.clusters * ms->smp.dies;
}

unsigned int machine_topo_get_threads_per_socket(const MachineState *ms)
{
    return ms->smp.threads * machine_topo_get_cores_per_socket(ms);
}

CpuTopologyLevel machine_get_cache_topo_level(const MachineState *ms,
                                              CacheLevelAndType cache)
{
    return ms->smp_cache.props[cache].topology;
}

void machine_set_cache_topo_level(MachineState *ms, CacheLevelAndType cache,
                                  CpuTopologyLevel level)
{
    ms->smp_cache.props[cache].topology = level;
}
