/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   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; either version 3, or (at your option)
   any later version.

   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.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#if defined(__i386__) || defined(__x86_64)
#include <cpuid.h>  /* GCC-provided */
#elif defined(__aarch64__)
#define ATTRIBUTE_UNUSED __attribute__((unused))

static inline uint_t __attribute_const__
__get_cpuid (unsigned int op ATTRIBUTE_UNUSED, unsigned int *eax,
	     unsigned int *ebx ATTRIBUTE_UNUSED,
	     unsigned int *ecx ATTRIBUTE_UNUSED, unsigned int *edx ATTRIBUTE_UNUSED)
{
  // CPUID bit assignments:
  // [31:24] IMPLEMENTER (0x50 - ARM_CPU_IMP_APM)
  // [23:20] VARIANT indicates processor revision (0x2 = Revision 2)
  // [19:16] Constant (Reads as 0xF)
  // [15:04] PARTNO indicates part number (0xC23 = Cortex-M3)
  // [03:00] REVISION indicates patch release (0x0 = Patch 0)
  //    unsigned long v = 0;
  //    __asm volatile ("MRS %[result], MPIDR_EL1" : [result] "=r" (v));
  //    Tprintf(DBG_LT0, "cpuid.c:%d read_cpuid_id() MPIDR_EL1=0x%016lx\n", __LINE__, v);
  uint_t res = 0;
  __asm volatile ("MRS %[result], MIDR_EL1" : [result] "=r" (*eax));
  Tprintf (DBG_LT0, "cpuid.c:%d read_cpuid_id() MIDR_EL1=0x%016x\n", __LINE__, *eax);
  return res;
}
#elif defined(__riscv)
#include <sched.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <asm/hwprobe.h>
#endif

/*
 * Various routines to handle identification
 * and classification of x86 processors.
 */

#define IS_GLOBAL /* externally visible */
#define	X86_VENDOR_Intel	0
#define	X86_VENDORSTR_Intel	"GenuineIntel"
#define	X86_VENDOR_IntelClone	1
#define	X86_VENDOR_AMD		2
#define	X86_VENDORSTR_AMD	"AuthenticAMD"

#define BITX(u, h, l)       (((u) >> (l)) & ((1LU << ((h) - (l) + 1LU)) - 1LU))
#define CPI_FAMILY_XTD(reg) BITX(reg, 27, 20)
#define CPI_MODEL_XTD(reg)  BITX(reg, 19, 16)
#define CPI_TYPE(reg)       BITX(reg, 13, 12)
#define CPI_FAMILY(reg)     BITX(reg, 11, 8)
#define CPI_STEP(reg)       BITX(reg, 3, 0)
#define CPI_MODEL(reg)      BITX(reg, 7, 4)
#define IS_EXTENDED_MODEL_INTEL(model)  ((model) == 0x6 || (model) >= 0xf)


typedef struct
{
  unsigned int eax;
  unsigned int ebx;
  unsigned int ecx;
  unsigned int edx;
} cpuid_regs_t;

typedef struct
{
  unsigned int cpi_model;
  unsigned int cpi_family;
  unsigned int cpi_vendor;        /* enum of cpi_vendorstr */
  unsigned int cpi_maxeax;        /* fn 0: %eax */
  char cpi_vendorstr[13];         /* fn 0: %ebx:%ecx:%edx */
} cpuid_info_t;


#if defined(__i386__) || defined(__x86_64)
static uint_t
cpuid_vendorstr_to_vendorcode (char *vendorstr)
{
  if (strcmp (vendorstr, X86_VENDORSTR_Intel) == 0)
    return X86_VENDOR_Intel;
  else if (strcmp (vendorstr, X86_VENDORSTR_AMD) == 0)
    return X86_VENDOR_AMD;
  else
    return X86_VENDOR_IntelClone;
}

static int
my_cpuid (unsigned int op, cpuid_regs_t *regs)
{
  regs->eax = regs->ebx = regs->ecx = regs->edx = 0;
  int ret = __get_cpuid (op, &regs->eax, &regs->ebx, &regs->ecx, &regs->edx);
  TprintfT (DBG_LT1, "my_cpuid: __get_cpuid(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) returns %d\n",
	    op, regs->eax, regs->ebx, regs->ecx, regs->edx, ret);
  return ret;
}
#endif

static cpuid_info_t *
get_cpuid_info ()
{
  static int cpuid_inited = 0;
  static cpuid_info_t cpuid_info;
  cpuid_info_t *cpi = &cpuid_info;
  if (cpuid_inited)
    return cpi;
  cpuid_inited = 1;

#if defined(__aarch64__)
  // CPUID bit assignments:
  // [31:24] IMPLEMENTER (0x50 - ARM_CPU_IMP_APM)
  // [23:20] VARIANT indicates processor revision (0x2 = Revision 2)
  // [19:16] Constant (Reads as 0xF)
  // [15:04] PARTNO indicates part number (0xC23 = Cortex-M3)
  // [03:00] REVISION indicates patch release (0x0 = Patch 0)
  uint_t reg = 0;
  __asm volatile ("MRS %[result], MIDR_EL1" : [result] "=r" (reg));
  cpi->cpi_vendor = reg >> 24;
  cpi->cpi_model = (reg >> 4) & 0xfff;
  switch (cpi->cpi_vendor)
    {
    case ARM_CPU_IMP_APM:
    case ARM_CPU_IMP_ARM:
    case ARM_CPU_IMP_CAVIUM:
    case ARM_CPU_IMP_BRCM:
    case ARM_CPU_IMP_QCOM:
      strncpy (cpi->cpi_vendorstr, AARCH64_VENDORSTR_ARM, sizeof (cpi->cpi_vendorstr));
      break;
    default:
      strncpy (cpi->cpi_vendorstr, "UNKNOWN ARM", sizeof (cpi->cpi_vendorstr));
      break;
    }
  Tprintf (DBG_LT0, "cpuid.c:%d read_cpuid_id() MIDR_EL1==0x%016x cpi_vendor=%d cpi_model=%d\n",
	   __LINE__, (unsigned int) reg, cpi->cpi_vendor, cpi->cpi_model);

#elif defined(__i386__) || defined(__x86_64)
  cpuid_regs_t regs;
  my_cpuid (0, &regs);
  cpi->cpi_maxeax = regs.eax;
  ((uint32_t *) cpi->cpi_vendorstr)[0] = regs.ebx;
  ((uint32_t *) cpi->cpi_vendorstr)[1] = regs.edx;
  ((uint32_t *) cpi->cpi_vendorstr)[2] = regs.ecx;
  cpi->cpi_vendorstr[12] = 0;
  cpi->cpi_vendor = cpuid_vendorstr_to_vendorcode (cpi->cpi_vendorstr);

  my_cpuid (1, &regs);
  cpi->cpi_model = CPI_MODEL (regs.eax);
  cpi->cpi_family = CPI_FAMILY (regs.eax);
  if (cpi->cpi_family == 0xf)
    cpi->cpi_family += CPI_FAMILY_XTD (regs.eax);

  /*
   * Beware: AMD uses "extended model" iff base *FAMILY* == 0xf.
   * Intel, and presumably everyone else, uses model == 0xf, as
   * one would expect (max value means possible overflow).  Sigh.
   */
  switch (cpi->cpi_vendor)
    {
    case X86_VENDOR_Intel:
      if (IS_EXTENDED_MODEL_INTEL (cpi->cpi_family))
	cpi->cpi_model += CPI_MODEL_XTD (regs.eax) << 4;
      break;
    case X86_VENDOR_AMD:
      if (CPI_FAMILY (cpi->cpi_family) == 0xf)
	cpi->cpi_model += CPI_MODEL_XTD (regs.eax) << 4;
      break;
    default:
      if (cpi->cpi_model == 0xf)
	cpi->cpi_model += CPI_MODEL_XTD (regs.eax) << 4;
      break;
    }
#elif defined(__riscv)
  #ifndef __riscv_hwprobe
	  cpi->cpi_vendor = 0;
	  cpi->cpi_family = 0;
	  cpi->cpi_model = 0;
  #else
		struct riscv_hwprobe res;
		res.key = RISCV_HWPROBE_KEY_MVENDORID;
		cpu_set_t cpu_set;
		int __riscv_hwprobe (struct riscv_hwprobe *pairs, 			\
					long pair_count, long cpu_count, 		\
					unsigned long *cpus, unsigned long flags)	\
	{
		return syscall(__NR_riscv_hwprobe, pairs, pair_count, cpu_count, cpus, flags);
	}
	CPU_ZERO(&cpu_set);
	CPU_SET(0, &cpu_set);
	long ret = __riscv_hwprobe(&res, 1, 1, &cpu_set, 0);
	cpi->cpi_vendor = res.value;
	cpi->cpi_family = 0;
	cpi->cpi_model = 0;
	#endif
#endif
  return cpi;
}

static inline uint_t
cpuid_getvendor ()
{
  return get_cpuid_info ()->cpi_vendor;
}

static inline uint_t
cpuid_getfamily ()
{
  return get_cpuid_info ()->cpi_family;
}

static inline uint_t
cpuid_getmodel ()
{
  return get_cpuid_info ()->cpi_model;
}
