/*
 * x86 host CPU functions, and "host" cpu type initialization
 *
 * Copyright 2021 SUSE LLC
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "host-cpu.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "sysemu/sysemu.h"

/* Note: Only safe for use on x86(-64) hosts */
static uint32_t host_cpu_phys_bits(void)
{
    uint32_t eax;
    uint32_t host_phys_bits;

    host_cpuid(0x80000000, 0, &eax, NULL, NULL, NULL);
    if (eax >= 0x80000008) {
        host_cpuid(0x80000008, 0, &eax, NULL, NULL, NULL);
        /*
         * Note: According to AMD doc 25481 rev 2.34 they have a field
         * at 23:16 that can specify a maximum physical address bits for
         * the guest that can override this value; but I've not seen
         * anything with that set.
         */
        host_phys_bits = eax & 0xff;
    } else {
        /*
         * It's an odd 64 bit machine that doesn't have the leaf for
         * physical address bits; fall back to 36 that's most older
         * Intel.
         */
        host_phys_bits = 36;
    }

    return host_phys_bits;
}

static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu)
{
    uint32_t host_phys_bits = host_cpu_phys_bits();
    uint32_t phys_bits = cpu->phys_bits;

    /*
     * Print a warning if the user set it to a value that's not the
     * host value.
     */
    if (phys_bits != host_phys_bits && phys_bits != 0) {
        warn_report_once("Host physical bits (%u)"
                         " does not match phys-bits property (%u)",
                         host_phys_bits, phys_bits);
    }

    if (cpu->host_phys_bits) {
        /* The user asked for us to use the host physical bits */
        phys_bits = host_phys_bits;
        if (cpu->host_phys_bits_limit &&
            phys_bits > cpu->host_phys_bits_limit) {
            phys_bits = cpu->host_phys_bits_limit;
        }
    }

    return phys_bits;
}

bool host_cpu_realizefn(CPUState *cs, Error **errp)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;

    if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
        uint32_t phys_bits = host_cpu_adjust_phys_bits(cpu);

        if (phys_bits &&
            (phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
             phys_bits < 32)) {
            error_setg(errp, "phys-bits should be between 32 and %u "
                       " (but is %u)",
                       TARGET_PHYS_ADDR_SPACE_BITS, phys_bits);
            return false;
        }
        cpu->phys_bits = phys_bits;
    }
    return true;
}

#define CPUID_MODEL_ID_SZ 48
/**
 * cpu_x86_fill_model_id:
 * Get CPUID model ID string from host CPU.
 *
 * @str should have at least CPUID_MODEL_ID_SZ bytes
 *
 * The function does NOT add a null terminator to the string
 * automatically.
 */
static int host_cpu_fill_model_id(char *str)
{
    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
    int i;

    for (i = 0; i < 3; i++) {
        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
        memcpy(str + i * 16 +  0, &eax, 4);
        memcpy(str + i * 16 +  4, &ebx, 4);
        memcpy(str + i * 16 +  8, &ecx, 4);
        memcpy(str + i * 16 + 12, &edx, 4);
    }
    return 0;
}

void host_cpu_vendor_fms(char *vendor, int *family, int *model, int *stepping)
{
    uint32_t eax, ebx, ecx, edx;

    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
    x86_cpu_vendor_words2str(vendor, ebx, edx, ecx);

    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
    if (family) {
        *family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
    }
    if (model) {
        *model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
    }
    if (stepping) {
        *stepping = eax & 0x0F;
    }
}

void host_cpu_instance_init(X86CPU *cpu)
{
    X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);

    if (xcc->model) {
        uint32_t ebx = 0, ecx = 0, edx = 0;
        char vendor[CPUID_VENDOR_SZ + 1];

        host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
        x86_cpu_vendor_words2str(vendor, ebx, edx, ecx);
        object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort);
    }
}

void host_cpu_max_instance_init(X86CPU *cpu)
{
    char vendor[CPUID_VENDOR_SZ + 1] = { 0 };
    char model_id[CPUID_MODEL_ID_SZ + 1] = { 0 };
    int family, model, stepping;

    /* Use max host physical address bits if -cpu max option is applied */
    object_property_set_bool(OBJECT(cpu), "host-phys-bits", true, &error_abort);

    host_cpu_vendor_fms(vendor, &family, &model, &stepping);
    host_cpu_fill_model_id(model_id);

    object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort);
    object_property_set_int(OBJECT(cpu), "family", family, &error_abort);
    object_property_set_int(OBJECT(cpu), "model", model, &error_abort);
    object_property_set_int(OBJECT(cpu), "stepping", stepping,
                            &error_abort);
    object_property_set_str(OBJECT(cpu), "model-id", model_id,
                            &error_abort);
}

static void host_cpu_class_init(ObjectClass *oc, void *data)
{
    X86CPUClass *xcc = X86_CPU_CLASS(oc);

    xcc->host_cpuid_required = true;
    xcc->ordering = 8;
    xcc->model_description =
        g_strdup_printf("processor with all supported host features ");
}

static const TypeInfo host_cpu_type_info = {
    .name = X86_CPU_TYPE_NAME("host"),
    .parent = X86_CPU_TYPE_NAME("max"),
    .class_init = host_cpu_class_init,
};

static void host_cpu_type_init(void)
{
    type_register_static(&host_cpu_type_info);
}

type_init(host_cpu_type_init);
