/*
 * QEMU RISC-V NUMA Helper
 *
 * Copyright (c) 2020 Western Digital Corporation or its affiliates.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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 "qemu/units.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "hw/boards.h"
#include "hw/qdev-properties.h"
#include "hw/riscv/numa.h"
#include "sysemu/device_tree.h"

static bool numa_enabled(const MachineState *ms)
{
    return (ms->numa_state && ms->numa_state->num_nodes) ? true : false;
}

int riscv_socket_count(const MachineState *ms)
{
    return (numa_enabled(ms)) ? ms->numa_state->num_nodes : 1;
}

int riscv_socket_first_hartid(const MachineState *ms, int socket_id)
{
    int i, first_hartid = ms->smp.cpus;

    if (!numa_enabled(ms)) {
        return (!socket_id) ? 0 : -1;
    }

    for (i = 0; i < ms->smp.cpus; i++) {
        if (ms->possible_cpus->cpus[i].props.node_id != socket_id) {
            continue;
        }
        if (i < first_hartid) {
            first_hartid = i;
        }
    }

    return (first_hartid < ms->smp.cpus) ? first_hartid : -1;
}

int riscv_socket_last_hartid(const MachineState *ms, int socket_id)
{
    int i, last_hartid = -1;

    if (!numa_enabled(ms)) {
        return (!socket_id) ? ms->smp.cpus - 1 : -1;
    }

    for (i = 0; i < ms->smp.cpus; i++) {
        if (ms->possible_cpus->cpus[i].props.node_id != socket_id) {
            continue;
        }
        if (i > last_hartid) {
            last_hartid = i;
        }
    }

    return (last_hartid < ms->smp.cpus) ? last_hartid : -1;
}

int riscv_socket_hart_count(const MachineState *ms, int socket_id)
{
    int first_hartid, last_hartid;

    if (!numa_enabled(ms)) {
        return (!socket_id) ? ms->smp.cpus : -1;
    }

    first_hartid = riscv_socket_first_hartid(ms, socket_id);
    if (first_hartid < 0) {
        return -1;
    }

    last_hartid = riscv_socket_last_hartid(ms, socket_id);
    if (last_hartid < 0) {
        return -1;
    }

    if (first_hartid > last_hartid) {
        return -1;
    }

    return last_hartid - first_hartid + 1;
}

bool riscv_socket_check_hartids(const MachineState *ms, int socket_id)
{
    int i, first_hartid, last_hartid;

    if (!numa_enabled(ms)) {
        return (!socket_id) ? true : false;
    }

    first_hartid = riscv_socket_first_hartid(ms, socket_id);
    if (first_hartid < 0) {
        return false;
    }

    last_hartid = riscv_socket_last_hartid(ms, socket_id);
    if (last_hartid < 0) {
        return false;
    }

    for (i = first_hartid; i <= last_hartid; i++) {
        if (ms->possible_cpus->cpus[i].props.node_id != socket_id) {
            return false;
        }
    }

    return true;
}

uint64_t riscv_socket_mem_offset(const MachineState *ms, int socket_id)
{
    int i;
    uint64_t mem_offset = 0;

    if (!numa_enabled(ms)) {
        return 0;
    }

    for (i = 0; i < ms->numa_state->num_nodes; i++) {
        if (i == socket_id) {
            break;
        }
        mem_offset += ms->numa_state->nodes[i].node_mem;
    }

    return (i == socket_id) ? mem_offset : 0;
}

uint64_t riscv_socket_mem_size(const MachineState *ms, int socket_id)
{
    if (!numa_enabled(ms)) {
        return (!socket_id) ? ms->ram_size : 0;
    }

    return (socket_id < ms->numa_state->num_nodes) ?
            ms->numa_state->nodes[socket_id].node_mem : 0;
}

void riscv_socket_fdt_write_id(const MachineState *ms, const char *node_name,
                               int socket_id)
{
    if (numa_enabled(ms)) {
        qemu_fdt_setprop_cell(ms->fdt, node_name, "numa-node-id", socket_id);
    }
}

void riscv_socket_fdt_write_distance_matrix(const MachineState *ms)
{
    int i, j, idx;
    g_autofree uint32_t *dist_matrix = NULL;
    uint32_t dist_matrix_size;

    if (numa_enabled(ms) && ms->numa_state->have_numa_distance) {
        dist_matrix_size = riscv_socket_count(ms) * riscv_socket_count(ms);
        dist_matrix_size *= (3 * sizeof(uint32_t));
        dist_matrix = g_malloc0(dist_matrix_size);

        for (i = 0; i < riscv_socket_count(ms); i++) {
            for (j = 0; j < riscv_socket_count(ms); j++) {
                idx = (i * riscv_socket_count(ms) + j) * 3;
                dist_matrix[idx + 0] = cpu_to_be32(i);
                dist_matrix[idx + 1] = cpu_to_be32(j);
                dist_matrix[idx + 2] =
                    cpu_to_be32(ms->numa_state->nodes[i].distance[j]);
            }
        }

        qemu_fdt_add_subnode(ms->fdt, "/distance-map");
        qemu_fdt_setprop_string(ms->fdt, "/distance-map", "compatible",
                                "numa-distance-map-v1");
        qemu_fdt_setprop(ms->fdt, "/distance-map", "distance-matrix",
                         dist_matrix, dist_matrix_size);
    }
}

CpuInstanceProperties
riscv_numa_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
{
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);

    assert(cpu_index < possible_cpus->len);
    return possible_cpus->cpus[cpu_index].props;
}

int64_t riscv_numa_get_default_cpu_node_id(const MachineState *ms, int idx)
{
    int64_t nidx = 0;

    if (ms->numa_state->num_nodes > ms->smp.cpus) {
        error_report("Number of NUMA nodes (%d)"
                     " cannot exceed the number of available CPUs (%u).",
                     ms->numa_state->num_nodes, ms->smp.cpus);
        exit(EXIT_FAILURE);
    }
    if (ms->numa_state->num_nodes) {
        nidx = idx / (ms->smp.cpus / ms->numa_state->num_nodes);
        if (ms->numa_state->num_nodes <= nidx) {
            nidx = ms->numa_state->num_nodes - 1;
        }
    }

    return nidx;
}

const CPUArchIdList *riscv_numa_possible_cpu_arch_ids(MachineState *ms)
{
    int n;
    unsigned int max_cpus = ms->smp.max_cpus;

    if (ms->possible_cpus) {
        assert(ms->possible_cpus->len == max_cpus);
        return ms->possible_cpus;
    }

    ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
                                  sizeof(CPUArchId) * max_cpus);
    ms->possible_cpus->len = max_cpus;
    for (n = 0; n < ms->possible_cpus->len; n++) {
        ms->possible_cpus->cpus[n].type = ms->cpu_type;
        ms->possible_cpus->cpus[n].arch_id = n;
        ms->possible_cpus->cpus[n].props.has_core_id = true;
        ms->possible_cpus->cpus[n].props.core_id = n;
    }

    return ms->possible_cpus;
}
