/*
 * 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, void *fdt,
                               const char *node_name, int socket_id)
{
    if (numa_enabled(ms)) {
        qemu_fdt_setprop_cell(fdt, node_name, "numa-node-id", socket_id);
    }
}

void riscv_socket_fdt_write_distance_matrix(const MachineState *ms, void *fdt)
{
    int i, j, idx;
    uint32_t *dist_matrix, 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(fdt, "/distance-map");
        qemu_fdt_setprop_string(fdt, "/distance-map", "compatible",
                                "numa-distance-map-v1");
        qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
                         dist_matrix, dist_matrix_size);
        g_free(dist_matrix);
    }
}

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) {
        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;
}
