/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2007 Advanced Micro Devices, Inc.
 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>,
 *	Raptor Engineering
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that 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.
 */

#include <arch/cpu.h>
#include <console/console.h>
#include <device/pci_ops.h>
#include <pc80/mc146818rtc.h>
#if IS_ENABLED(CONFIG_HAVE_OPTION_TABLE)
#include "option_table.h"
#endif

#include "cpu/amd/quadcore/quadcore_id.c"

u32 get_core_num_in_bsp(u32 nodeid)
{
	u32 dword;
	if (is_fam15h()) {
		/* Family 15h moved CmpCap to F5x84 [7:0] */
		dword = pci_read_config32(NODE_PCI(nodeid, 5), 0x84);
		dword &= 0xff;
	} else {
		dword = pci_read_config32(NODE_PCI(nodeid, 3), 0xe8);
		dword >>= 12;
		/* Bit 15 is CmpCap[2] since Revision D. */
		if ((cpuid_ecx(0x80000008) & 0xff) > 3)
			dword = ((dword & 8) >> 1) | (dword & 3);
		else
			dword &= 3;
	}
	return dword;
}

u8 set_apicid_cpuid_lo(void)
{
	// set the NB_CFG[54]=1; why the OS will be happy with that ???
	msr_t msr;
	msr = rdmsr(NB_CFG_MSR);
	msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo
	wrmsr(NB_CFG_MSR, msr);

	return 1;
}

void real_start_other_core(uint32_t nodeid, uint32_t cores)
{
	ssize_t i;
	uint32_t dword;

	printk(BIOS_DEBUG,
		"Start other core - nodeid: %02x  cores: %02x\n", nodeid, cores);

	/* set PCI_DEV(0, 0x18+nodeid, 3), 0x44 bit 27 to redirect all MC4
	   accesses and error logging to core0 */
	dword = pci_read_config32(NODE_PCI(nodeid, 3), 0x44);
	dword |= 1 << 30;	/* SyncFloodOnDramAdrParErr=1 */
	dword |= 1 << 27;	/* NbMcaToMstCpuEn=1 */
	dword |= 1 << 21;	/* SyncFloodOnAnyUcErr=1 */
	dword |= 1 << 20;	/* SyncFloodOnWDT=1 */
	dword |= 1 << 2;	/* SyncFloodOnDramUcEcc=1 */
	pci_write_config32(NODE_PCI(nodeid, 3), 0x44, dword);
	if (is_fam15h()) {
		uint32_t core_activation_flags = 0;
		uint32_t active_cores = 0;

		/* Set PCI_DEV(0, 0x18+nodeid, 0),
		 * 0x1dc bits 7:1 to start cores
		 */
		dword = pci_read_config32(NODE_PCI(nodeid, 0), 0x1dc);
		for (i = 1; i < cores + 1; i++)
			core_activation_flags |= 1 << i;
		/* Start the first core of each compute unit */
		active_cores |= core_activation_flags & 0x55;
		pci_write_config32(NODE_PCI(nodeid, 0), 0x1dc, dword
				  | active_cores);

		/* Each core shares a single set of MTRR registers with
		 * another core in the same compute unit, therefore, it
		 * is important that one core in each CU starts in advance
		 * of the other in order to avoid one core stomping all over
		 * the other core's settings.
		 */

		/* Wait for the first core of each compute unit to start... */
		uint32_t timeout;
		for (i = 1; i < cores + 1; i++) {
			if (!(i & 0x1)) {
				uint32_t ap_apicid =
				get_boot_apic_id(nodeid, i);
				timeout = wait_cpu_state(ap_apicid,
							F10_APSTATE_ASLEEP, F10_APSTATE_ASLEEP);
			}
		}

		/* Start the second core of each compute unit */
		active_cores |= core_activation_flags & 0xaa;
		pci_write_config32(NODE_PCI(nodeid, 0), 0x1dc, dword |
				   active_cores);
	} else {
		// set PCI_DEV(0, 0x18+nodeid, 0), 0x68 bit 5 to start core1
		dword = pci_read_config32(NODE_PCI(nodeid, 0), 0x68);
		dword |= 1 << 5;
		pci_write_config32(NODE_PCI(nodeid, 0), 0x68, dword);

		if (cores > 1) {
			dword = pci_read_config32(NODE_PCI(nodeid, 0), 0x168);
			for (i = 0; i < cores - 1; i++)
				dword |= 1 << i;
			pci_write_config32(NODE_PCI(nodeid, 0), 0x168, dword);
		}
	}
}

#if (!IS_ENABLED(CONFIG_CPU_AMD_MODEL_10XXX))
//it is running on core0 of node0
static void start_other_cores(void)
{
	u32 nodes;
	u32 nodeid;

	// disable multi_core
	if (read_option(multi_core, 0) != 0)  {
		printk(BIOS_DEBUG, "Skip additional core init\n");
		return;
	}

	nodes = get_nodes();

	for (nodeid = 0; nodeid < nodes; nodeid++) {
		u32 cores = get_core_num_in_bsp(nodeid);
		printk(BIOS_DEBUG, "init node: %02x  cores: %02x pass 1\n",
			nodeid, cores);
		if (cores > 0)
			real_start_other_core(nodeid, cores);
	}
}
#endif
