/*
 * PPC CPU identification
 *
 * This is a very simple "host CPU info" struct to get us going.
 * For the little host information we need, I don't want to grub about
 * parsing stuff in /proc/device-tree so just match host PVR to differentiate
 * PPC970 and POWER7 (which is all that's currently supported).
 *
 * Qemu does something similar but this is MUCH simpler!
 *
 * Copyright 2012 Matt Evans <matt@ozlabs.org>, IBM Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include <kvm/kvm.h>
#include <sys/ioctl.h>

#include "cpu_info.h"
#include "kvm/util.h"

/* POWER7 */

static struct cpu_info cpu_power7_info = {
	.name = "POWER7",
	.tb_freq = 512000000,
	.d_bsize = 128,
	.i_bsize = 128,
	.flags = CPUINFO_FLAG_DFP | CPUINFO_FLAG_VSX | CPUINFO_FLAG_VMX,
	.mmu_info = {
		.flags = KVM_PPC_PAGE_SIZES_REAL | KVM_PPC_1T_SEGMENTS,
		.slb_size = 32,
	},
};

/* POWER8 */

static struct cpu_info cpu_power8_info = {
	.name = "POWER8",
	.tb_freq = 512000000,
	.d_bsize = 128,
	.i_bsize = 128,
	.flags = CPUINFO_FLAG_DFP | CPUINFO_FLAG_VSX | CPUINFO_FLAG_VMX,
	.mmu_info = {
		.flags = KVM_PPC_PAGE_SIZES_REAL | KVM_PPC_1T_SEGMENTS,
		.slb_size = 32,
	},
};

/* PPC970/G5 */

static struct cpu_info cpu_970_info = {
	.name = "G5",
	.tb_freq = 33333333,
	.d_bsize = 128,
	.i_bsize = 128,
	.flags = CPUINFO_FLAG_VMX,
};

/* This is a default catchall for 'no match' on PVR: */
static struct cpu_info cpu_dummy_info = { .name = "unknown" };

static struct pvr_info host_pvr_info[] = {
	{ 0xffffffff, 0x0f000003, &cpu_power7_info },
	{ 0xffff0000, 0x003f0000, &cpu_power7_info },
	{ 0xffff0000, 0x004a0000, &cpu_power7_info },
	{ 0xffff0000, 0x004b0000, &cpu_power8_info },
	{ 0xffff0000, 0x00390000, &cpu_970_info },
	{ 0xffff0000, 0x003c0000, &cpu_970_info },
        { 0xffff0000, 0x00440000, &cpu_970_info },
        { 0xffff0000, 0x00450000, &cpu_970_info },
};

/* If we can't query the kernel for supported page sizes assume 4K and 16M */
static struct kvm_ppc_one_seg_page_size fallback_sps[] = {
	[0] = {
		.page_shift = 12,
		.slb_enc    = 0,
		.enc =  {
			[0] = {
				.page_shift = 12,
				.pte_enc    = 0,
			},
		},
	},
	[1] = {
		.page_shift = 24,
		.slb_enc    = 0x100,
		.enc =  {
			[0] = {
				.page_shift = 24,
				.pte_enc    = 0,
			},
		},
	},
};


static void setup_mmu_info(struct kvm *kvm, struct cpu_info *cpu_info)
{
	static struct kvm_ppc_smmu_info *mmu_info;
	struct kvm_ppc_one_seg_page_size *sps;
	int i, j, k, valid;

	if (!kvm__supports_extension(kvm, KVM_CAP_PPC_GET_SMMU_INFO)) {
		memcpy(&cpu_info->mmu_info.sps, fallback_sps, sizeof(fallback_sps));
	} else if (ioctl(kvm->vm_fd, KVM_PPC_GET_SMMU_INFO, &cpu_info->mmu_info) < 0) {
			die_perror("KVM_PPC_GET_SMMU_INFO failed");
	}

	mmu_info = &cpu_info->mmu_info;

	if (!(mmu_info->flags & KVM_PPC_PAGE_SIZES_REAL))
		/* Guest pages are not restricted by the backing page size */
		return;

	/* Filter based on backing page size */

	for (i = 0; i < KVM_PPC_PAGE_SIZES_MAX_SZ; i++) {
		sps = &mmu_info->sps[i];

		if (!sps->page_shift)
			break;

		if (kvm->ram_pagesize < (1ul << sps->page_shift)) {
			/* Mark the whole segment size invalid */
			sps->page_shift = 0;
			continue;
		}

		/* Check each page size for the segment */
		for (j = 0, valid = 0; j < KVM_PPC_PAGE_SIZES_MAX_SZ; j++) {
			if (!sps->enc[j].page_shift)
				break;

			if (kvm->ram_pagesize < (1ul << sps->enc[j].page_shift))
				sps->enc[j].page_shift = 0;
			else
				valid++;
		}

		if (!valid) {
			/* Mark the whole segment size invalid */
			sps->page_shift = 0;
			continue;
		}

		/* Mark any trailing entries invalid if we broke out early */
		for (k = j; k < KVM_PPC_PAGE_SIZES_MAX_SZ; k++)
			sps->enc[k].page_shift = 0;

		/* Collapse holes */
		for (j = 0; j < KVM_PPC_PAGE_SIZES_MAX_SZ; j++) {
			if (sps->enc[j].page_shift)
				continue;

			for (k = j + 1; k < KVM_PPC_PAGE_SIZES_MAX_SZ; k++) {
				if (sps->enc[k].page_shift) {
					sps->enc[j] = sps->enc[k];
					sps->enc[k].page_shift = 0;
					break;
				}
			}
		}
	}

	/* Mark any trailing entries invalid if we broke out early */
	for (j = i; j < KVM_PPC_PAGE_SIZES_MAX_SZ; j++)
		mmu_info->sps[j].page_shift = 0;

	/* Collapse holes */
	for (i = 0; i < KVM_PPC_PAGE_SIZES_MAX_SZ; i++) {
		if (mmu_info->sps[i].page_shift)
			continue;

		for (j = i + 1; j < KVM_PPC_PAGE_SIZES_MAX_SZ; j++) {
			if (mmu_info->sps[j].page_shift) {
				mmu_info->sps[i] = mmu_info->sps[j];
				mmu_info->sps[j].page_shift = 0;
				break;
			}
		}
	}
}

struct cpu_info *find_cpu_info(struct kvm *kvm)
{
	struct cpu_info *info;
	unsigned int i;
	u32 pvr = kvm->arch.pvr;

	for (info = NULL, i = 0; i < ARRAY_SIZE(host_pvr_info); i++) {
		if ((pvr & host_pvr_info[i].pvr_mask) == host_pvr_info[i].pvr) {
			info = host_pvr_info[i].cpu_info;
			break;
		}
	}

	/* Didn't find anything? Rut-ro. */
	if (!info) {
		pr_warning("Host CPU unsupported by kvmtool\n");
		info = &cpu_dummy_info;
	}

	setup_mmu_info(kvm, info);

	return info;
}
