// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2013-2019 IBM Corp. */

#include <skiboot.h>
#include <chip.h>
#include <console.h>
#include <device.h>
#include <timebase.h>
#include <cpu.h>

static struct proc_chip *chips[MAX_CHIPS];
enum proc_chip_quirks proc_chip_quirks;

uint32_t pir_to_chip_id(uint32_t pir)
{
	if (proc_gen == proc_gen_p10)
		return P10_PIR2GCID(pir);
	else if (proc_gen == proc_gen_p9)
		return P9_PIR2GCID(pir);
	else if (proc_gen == proc_gen_p8)
		return P8_PIR2GCID(pir);
	else
		assert(false);
}

uint32_t pir_to_core_id(uint32_t pir)
{
	if (proc_gen == proc_gen_p10) {
		if (this_cpu()->is_fused_core)
			return P10_PIRFUSED2NORMALCOREID(pir);
		else
			return P10_PIR2COREID(pir);
	} else if (proc_gen == proc_gen_p9) {
		if (this_cpu()->is_fused_core)
			return P9_PIRFUSED2NORMALCOREID(pir);
		else
			return P9_PIR2COREID(pir);
	} else if (proc_gen == proc_gen_p8) {
		return P8_PIR2COREID(pir);
	} else {
		assert(false);
	}
}

uint32_t pir_to_fused_core_id(uint32_t pir)
{
	if (proc_gen == proc_gen_p10) {
		if (this_cpu()->is_fused_core)
			return P10_PIR2FUSEDCOREID(pir);
		else
			return P10_PIR2COREID(pir);
	} else if (proc_gen == proc_gen_p9) {
		if (this_cpu()->is_fused_core)
			return P9_PIR2FUSEDCOREID(pir);
		else
			return P9_PIR2COREID(pir);
	} else if (proc_gen == proc_gen_p8) {
		return P8_PIR2COREID(pir);
	} else {
		assert(false);
	}
}

uint32_t pir_to_thread_id(uint32_t pir)
{
	if (proc_gen == proc_gen_p10) {
		if (this_cpu()->is_fused_core)
			return P10_PIRFUSED2NORMALTHREADID(pir);
		else
			return P10_PIR2THREADID(pir);
	} else if (proc_gen == proc_gen_p9) {
		if (this_cpu()->is_fused_core)
			return P9_PIRFUSED2NORMALTHREADID(pir);
		else
			return P9_PIR2THREADID(pir);
	} else if (proc_gen == proc_gen_p8) {
		return P8_PIR2THREADID(pir);
	} else {
		assert(false);
	}
}

struct proc_chip *next_chip(struct proc_chip *chip)
{
	unsigned int i;

	for (i = chip ? (chip->id + 1) : 0; i < MAX_CHIPS; i++)
		if (chips[i])
			return chips[i];
	return NULL;
}


struct proc_chip *get_chip(uint32_t chip_id)
{
	if (chip_id >= MAX_CHIPS)
		return NULL;
	return chips[chip_id];
}

static void init_chip(struct dt_node *dn)
{
	struct proc_chip *chip;
	uint32_t id;
	const char *lc = NULL;

	id = dt_get_chip_id(dn);
	assert(id < MAX_CHIPS);
	assert(chips[id] == NULL);

	chip = zalloc(sizeof(struct proc_chip));
	assert(chip);

	chip->id = id;
	chip->devnode = dn;

	chip->dbob_id = dt_prop_get_u32_def(dn, "ibm,dbob-id", 0xffffffff);
	chip->pcid = dt_prop_get_u32_def(dn, "ibm,proc-chip-id", 0xffffffff);

	if (dt_prop_get_u32_def(dn, "ibm,occ-functional-state", 0))
		chip->occ_functional = true;
	else
		chip->occ_functional = false;

	list_head_init(&chip->i2cms);

	/* Update the location code for this chip. */
	if (dt_has_node_property(dn, "ibm,loc-code", NULL))
		lc = dt_prop_get(dn, "ibm,loc-code");
	else if (dt_has_node_property(dn, "ibm,slot-location-code", NULL))
		lc = dt_prop_get(dn, "ibm,slot-location-code");

	if (lc)
		chip->loc_code = strdup(lc);

	chip->primary_topology = dt_prop_get_u32_def(dn,
		"ibm,primary-topology-index", 0xffffffff);

	prlog(PR_INFO, "CHIP: Initialised chip %d from %s\n", id, dn->name);
	chips[id] = chip;
}

void init_chips(void)
{
	struct dt_node *xn;

	/* Detect mambo chip */
	if (dt_find_by_path(dt_root, "/mambo")) {
		proc_chip_quirks |= QUIRK_NO_CHIPTOD | QUIRK_MAMBO_CALLOUTS
			| QUIRK_NO_F000F | QUIRK_NO_PBA | QUIRK_NO_OCC_IRQ
			| QUIRK_NO_RNG;

		enable_mambo_console();

		prlog(PR_NOTICE, "CHIP: Detected Mambo simulator\n");

		dt_for_each_compatible(dt_root, xn, "ibm,mambo-chip")
			init_chip(xn);
	}

	/* Detect simics */
	if (dt_find_by_path(dt_root, "/simics")) {
		proc_chip_quirks |= QUIRK_SIMICS
			| QUIRK_NO_PBA | QUIRK_NO_OCC_IRQ | QUIRK_SLOW_SIM;
		tb_hz = 512000;
		prlog(PR_NOTICE, "CHIP: Detected Simics simulator\n");
	}
	/* Detect Awan emulator */
	xn = dt_find_by_path(dt_root, "/awan");
	if (xn) {
		const char *model_type;
		proc_chip_quirks |= QUIRK_AWAN | QUIRK_SLOW_SIM | QUIRK_NO_PBA
			| QUIRK_NO_OCC_IRQ;
		tb_hz = 512000;

		model_type = dt_prop_get_def(xn, "device_type", (void *)"core");
		if (strcmp(model_type, "core") == 0) {
			proc_chip_quirks |= QUIRK_NO_RNG | QUIRK_NO_CHIPTOD
				| QUIRK_NO_F000F;
		}
		prlog(PR_NOTICE, "CHIP: Detected Awan emulator %s model\n",
				model_type);
	}
	/* Detect Qemu */
	if (dt_node_is_compatible(dt_root, "qemu,powernv") ||
	    dt_node_is_compatible(dt_root, "qemu,powernv8") ||
	    dt_node_is_compatible(dt_root, "qemu,powernv9") ||
	    dt_node_is_compatible(dt_root, "qemu,powernv10") ||
	    dt_find_by_path(dt_root, "/qemu")) {
		proc_chip_quirks |= QUIRK_QEMU | QUIRK_NO_DIRECT_CTL | QUIRK_NO_RNG;
		prlog(PR_NOTICE, "CHIP: Detected QEMU simulator\n");
	}

	/* We walk the chips based on xscom nodes in the tree */
	dt_for_each_compatible(dt_root, xn, "ibm,xscom") {
		init_chip(xn);
	}
}
