/* Copyright (C) 2009 Intel Corporation 
   Author: Andi Kleen
   Common Intel CPU code.

   mcelog 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.

   mcelog 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.

   You should find a copy of v2 of the GNU General Public License somewhere
   on your Linux system; if not, write to the Free Software Foundation, 
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stddef.h>
#include "mcelog.h"
#include "intel.h"
#include "bitfield.h"
#include "nehalem.h"
#include "memdb.h"
#include "page.h"
#include "sandy-bridge.h"
#include "ivy-bridge.h"
#include "haswell.h"

int memory_error_support;

void intel_cpu_init(enum cputype cpu)
{
	if (cpu == CPU_NEHALEM || cpu == CPU_XEON75XX || cpu == CPU_INTEL ||
	    cpu == CPU_SANDY_BRIDGE || cpu == CPU_SANDY_BRIDGE_EP ||
	    cpu == CPU_IVY_BRIDGE || cpu == CPU_IVY_BRIDGE_EPEX ||
	    cpu == CPU_HASWELL || cpu == CPU_HASWELL_EPEX || cpu == CPU_BROADWELL ||
	    cpu == CPU_BROADWELL_DE || cpu == CPU_BROADWELL_EPEX ||
	    cpu == CPU_KNIGHTS_LANDING || cpu == CPU_KNIGHTS_MILL ||
	    cpu == CPU_SKYLAKE || cpu == CPU_SKYLAKE_XEON ||
	    cpu == CPU_KABYLAKE || cpu == CPU_DENVERTON)
		memory_error_support = 1;
}

enum cputype select_intel_cputype(int family, int model)
{
	if (family == 15) { 
		if (model == 6) 
			return CPU_TULSA;
		return CPU_P4;
	} 
	if (family == 6) { 
		if (model >= 0x1a && model != 28) 
			memory_error_support = 1;

		if (model < 0xf) 
			return CPU_P6OLD;
		else if (model == 0xf || model == 0x17) /* Merom/Penryn */
			return CPU_CORE2;
		else if (model == 0x1d)
			return CPU_DUNNINGTON;
		else if (model == 0x1a || model == 0x2c || model == 0x1e ||
			 model == 0x25)
			return CPU_NEHALEM;
		else if (model == 0x2e || model == 0x2f)
			return CPU_XEON75XX;
		else if (model == 0x2a)
			return CPU_SANDY_BRIDGE;
		else if (model == 0x2d)
			return CPU_SANDY_BRIDGE_EP;
		else if (model == 0x3a)
			return CPU_IVY_BRIDGE;
		else if (model == 0x3e)
			return CPU_IVY_BRIDGE_EPEX;
		else if (model == 0x3c || model == 0x45 || model == 0x46)
			return CPU_HASWELL;
		else if (model == 0x3f)
			return CPU_HASWELL_EPEX;
		else if (model == 0x3d)
			return CPU_BROADWELL;
		else if (model == 0x4f)
			return CPU_BROADWELL_EPEX;
		else if (model == 0x56)
			return CPU_BROADWELL_DE;
		else if (model == 0x57)
			return CPU_KNIGHTS_LANDING;
		else if (model == 0x85)
			return CPU_KNIGHTS_MILL;
		else if (model == 0x1c || model == 0x26 || model == 0x27 ||
			 model == 0x35 || model == 0x36 || model == 0x36 ||
			 model == 0x37 || model == 0x4a || model == 0x4c ||
			 model == 0x4d || model == 0x5a || model == 0x5d)
			return CPU_ATOM;
		else if (model == 0x4e || model == 0x5e)
			return CPU_SKYLAKE;
		else if (model == 0x55)
			return CPU_SKYLAKE_XEON;
		else if (model == 0x8E || model == 0x9E)
			return CPU_KABYLAKE;
		else if (model == 0x5f)
			return CPU_DENVERTON;
		if (model > 0x1a) {
			Eprintf("Family 6 Model %u CPU: only decoding architectural errors\n",
				model);
			return CPU_INTEL; 
		}
	}
	if (family > 6) { 
		Eprintf("Family %u Model %u CPU: only decoding architectural errors\n",
				family, model);
		return CPU_INTEL;
	}
	Eprintf("Unknown Intel CPU type family %u model %u\n", family, model);
	return family == 6 ? CPU_P6OLD : CPU_GENERIC;
}

int is_intel_cpu(int cpu)
{
	switch (cpu) {
	CASE_INTEL_CPUS:
		return 1;
	} 
	return 0;
}

static int intel_memory_error(struct mce *m, unsigned recordlen)
{
	u32 mca = m->status & 0xffff;
	if ((mca >> 7) == 1) { 
		unsigned corr_err_cnt = 0;
		int channel[2] = { (mca & 0xf) == 0xf ? -1 : (int)(mca & 0xf), -1 };
		int dimm[2] = { -1, -1 };

		switch (cputype) { 
		case CPU_NEHALEM:
			nehalem_memerr_misc(m, channel, dimm);
			break;
		case CPU_SANDY_BRIDGE_EP:
			sandy_bridge_ep_memerr_misc(m, channel, dimm);
			break;
		case CPU_IVY_BRIDGE_EPEX:
			ivy_bridge_ep_memerr_misc(m, channel, dimm);
			break;
		default:
			break;
		} 

		if (recordlen > offsetof(struct mce, mcgcap) && m->mcgcap & MCG_CMCI_P)
 			corr_err_cnt = EXTRACT(m->status, 38, 52);
		memory_error(m, channel[0], dimm[0], corr_err_cnt, recordlen);
		account_page_error(m, channel[0], dimm[0]);

		/* 
		 * When both DIMMs have a error account the error twice to the page.
		 */
		if (channel[1] != -1) {
			memory_error(m, channel[1], dimm[1], corr_err_cnt, recordlen);
			account_page_error(m, channel[1], dimm[1]);
		}

		return 1;
	}

	return 0;
}

/* No bugs known, but filter out memory errors if the user asked for it */
int mce_filter_intel(struct mce *m, unsigned recordlen)
{
	if (intel_memory_error(m, recordlen) == 1) 
		return !filter_memory_errors;
	return 1;
}
