/* Copyright (C) 2021-2025 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__)
#if !defined(ATTRIBUTE_UNUSED)
#define ATTRIBUTE_UNUSED __attribute__((unused))
#endif

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>
#ifdef HAVE_ASM_HWPROBE_H
#include <asm/hwprobe.h>
#endif
#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)
  #if !defined(__riscv_hwprobe) || !defined(HAVE_ASM_HWPROBE_H)
	  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;
}
