ARC: Improve identification of ARC cores
1. Try to guess a ARC core template that was used i.e. not just name a core family but something more menaingful like "ARC HS38", "ARC EM11D" etc. We do it checking availability of the key differentiation features like: - Caches (we actually only check for L1 I$ fpr simplicity) - XY-memory - DSP extensions etc. 2. Identify ARC subsystems 3. Print core clock frequency Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
This commit is contained in:
parent
ad74bb4fe3
commit
85e529fdfc
@ -16,6 +16,20 @@
|
||||
* access: "lr"/"sr".
|
||||
*/
|
||||
|
||||
/*
|
||||
* Typically 8 least significant bits of Build Configuration Register (BCR)
|
||||
* describe version of the HW block in question. Moreover if decoded version
|
||||
* is 0 this means given HW block is absent - this is especially useful because
|
||||
* we may safely read BRC regardless HW block existence while an attempt to
|
||||
* access any other AUX regs associated with this HW block lead to imediate
|
||||
* "instruction error" exception.
|
||||
*
|
||||
* I.e. before using any cofigurable HW block it's required to make sure it
|
||||
* exists at all, and for that we introduce a special macro below.
|
||||
*/
|
||||
#define ARC_BCR_VERSION_MASK GENMASK(7, 0)
|
||||
#define ARC_FEATURE_EXISTS(bcr) !!(__builtin_arc_lr(bcr) & ARC_BCR_VERSION_MASK)
|
||||
|
||||
#define ARC_AUX_IDENTITY 0x04
|
||||
#define ARC_AUX_STATUS32 0x0a
|
||||
|
||||
@ -73,7 +87,7 @@
|
||||
#define ARC_BCR_CLUSTER 0xcf
|
||||
|
||||
/* MMU Management regs */
|
||||
#define ARC_AUX_MMU_BCR 0x06f
|
||||
#define ARC_AUX_MMU_BCR 0x6f
|
||||
|
||||
/* IO coherency related auxiliary registers */
|
||||
#define ARC_AUX_IO_COH_ENABLE 0x500
|
||||
@ -81,6 +95,15 @@
|
||||
#define ARC_AUX_IO_COH_AP0_BASE 0x508
|
||||
#define ARC_AUX_IO_COH_AP0_SIZE 0x509
|
||||
|
||||
/* XY-memory related */
|
||||
#define ARC_AUX_XY_BUILD 0x79
|
||||
|
||||
/* DSP-extensions related auxiliary registers */
|
||||
#define ARC_AUX_DSP_BUILD 0x7A
|
||||
|
||||
/* ARC Subsystems related auxiliary registers */
|
||||
#define ARC_AUX_SUBSYS_BUILD 0xF0
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/* Accessors for auxiliary registers */
|
||||
#define read_aux_reg(reg) __builtin_arc_lr(reg)
|
||||
|
@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/arcregs.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
@ -35,34 +36,193 @@ int dram_init(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DISPLAY_CPUINFO
|
||||
const char *decode_identity(void)
|
||||
const char *arc_700_version(int arcver, char *name, int name_len)
|
||||
{
|
||||
int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
|
||||
const char *arc_ver;
|
||||
|
||||
switch (arcver) {
|
||||
/* ARCompact cores */
|
||||
case 0x32: return "ARC 700 v4.4-4.5";
|
||||
case 0x33: return "ARC 700 v4.6-v4.9";
|
||||
case 0x34: return "ARC 700 v4.10";
|
||||
case 0x35: return "ARC 700 v4.11";
|
||||
|
||||
/* ARCv2 cores */
|
||||
case 0x41: return "ARC EM v1.1a";
|
||||
case 0x42: return "ARC EM v3.0";
|
||||
case 0x43: return "ARC EM v4.0";
|
||||
case 0x50: return "ARC HS v1.0";
|
||||
case 0x51: return "ARC EM v2.0";
|
||||
case 0x52: return "ARC EM v2.1";
|
||||
case 0x53: return "ARC HS v3.0";
|
||||
case 0x54: return "ARC HS v4.0";
|
||||
|
||||
default: return "Unknown ARC core";
|
||||
case 0x32:
|
||||
arc_ver = "v4.4-4.5";
|
||||
break;
|
||||
case 0x33:
|
||||
arc_ver = "v4.6-v4.9";
|
||||
break;
|
||||
case 0x34:
|
||||
arc_ver = "v4.10";
|
||||
break;
|
||||
case 0x35:
|
||||
arc_ver = "v4.11";
|
||||
break;
|
||||
default:
|
||||
arc_ver = "unknown version";
|
||||
}
|
||||
|
||||
snprintf(name, name_len, "ARC 700 %s", arc_ver);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
struct em_template_t {
|
||||
const bool cache;
|
||||
const bool dsp;
|
||||
const bool xymem;
|
||||
const char name[8];
|
||||
};
|
||||
|
||||
static const struct em_template_t em_versions[] = {
|
||||
{false, false, false, "EM4"},
|
||||
{true, false, false, "EM6"},
|
||||
{false, true, false, "EM5D"},
|
||||
{true, true, false, "EM7D"},
|
||||
{false, true, true, "EM9D"},
|
||||
{true, true, true, "EM11D"},
|
||||
};
|
||||
|
||||
const char *arc_em_version(int arcver, char *name, int name_len)
|
||||
{
|
||||
const char *arc_name = "EM";
|
||||
const char *arc_ver;
|
||||
bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
|
||||
bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
|
||||
bool xymem = ARC_FEATURE_EXISTS(ARC_AUX_XY_BUILD);
|
||||
int i;
|
||||
|
||||
for (i = 0; i++ < sizeof(em_versions) / sizeof(struct em_template_t);) {
|
||||
if (em_versions[i].cache == cache &&
|
||||
em_versions[i].dsp == dsp &&
|
||||
em_versions[i].xymem == xymem) {
|
||||
arc_name = em_versions[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (arcver) {
|
||||
case 0x41:
|
||||
arc_ver = "v1.1a";
|
||||
break;
|
||||
case 0x42:
|
||||
arc_ver = "v3.0";
|
||||
break;
|
||||
case 0x43:
|
||||
arc_ver = "v4.0";
|
||||
break;
|
||||
case 0x44:
|
||||
arc_ver = "v5.0";
|
||||
break;
|
||||
default:
|
||||
arc_ver = "unknown version";
|
||||
}
|
||||
|
||||
snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
struct hs_template_t {
|
||||
const bool cache;
|
||||
const bool mmu;
|
||||
const bool dual_issue;
|
||||
const bool dsp;
|
||||
const char name[8];
|
||||
};
|
||||
|
||||
static const struct hs_template_t hs_versions[] = {
|
||||
{false, false, false, false, "HS34"},
|
||||
{true, false, false, false, "HS36"},
|
||||
{true, true, false, false, "HS38"},
|
||||
{false, false, true, false, "HS44"},
|
||||
{true, false, true, false, "HS46"},
|
||||
{true, true, true, false, "HS48"},
|
||||
{false, false, true, true, "HS45D"},
|
||||
{true, false, true, true, "HS47D"},
|
||||
};
|
||||
|
||||
const char *arc_hs_version(int arcver, char *name, int name_len)
|
||||
{
|
||||
const char *arc_name = "HS";
|
||||
const char *arc_ver;
|
||||
bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
|
||||
bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
|
||||
bool mmu = !!read_aux_reg(ARC_AUX_MMU_BCR);
|
||||
bool dual_issue = arcver == 0x54 ? true : false;
|
||||
int i;
|
||||
|
||||
for (i = 0; i++ < sizeof(hs_versions) / sizeof(struct hs_template_t);) {
|
||||
if (hs_versions[i].cache == cache &&
|
||||
hs_versions[i].mmu == mmu &&
|
||||
hs_versions[i].dual_issue == dual_issue &&
|
||||
hs_versions[i].dsp == dsp) {
|
||||
arc_name = hs_versions[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (arcver) {
|
||||
case 0x50:
|
||||
arc_ver = "v1.0";
|
||||
break;
|
||||
case 0x51:
|
||||
arc_ver = "v2.0";
|
||||
break;
|
||||
case 0x52:
|
||||
arc_ver = "v2.1c";
|
||||
break;
|
||||
case 0x53:
|
||||
arc_ver = "v3.0";
|
||||
break;
|
||||
case 0x54:
|
||||
arc_ver = "v4.0";
|
||||
break;
|
||||
default:
|
||||
arc_ver = "unknown version";
|
||||
}
|
||||
|
||||
snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
const char *decode_identity(void)
|
||||
{
|
||||
#define MAX_CPU_NAME_LEN 64
|
||||
|
||||
int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
|
||||
char *name = malloc(MAX_CPU_NAME_LEN);
|
||||
|
||||
if (arcver >= 0x50)
|
||||
return arc_hs_version(arcver, name, MAX_CPU_NAME_LEN);
|
||||
else if (arcver >= 0x40)
|
||||
return arc_em_version(arcver, name, MAX_CPU_NAME_LEN);
|
||||
else if (arcver >= 0x30)
|
||||
return arc_700_version(arcver, name, MAX_CPU_NAME_LEN);
|
||||
else
|
||||
return "Unknown ARC core";
|
||||
}
|
||||
|
||||
const char *decode_subsystem(void)
|
||||
{
|
||||
int subsys_type = read_aux_reg(ARC_AUX_SUBSYS_BUILD) & GENMASK(3, 0);
|
||||
|
||||
switch (subsys_type) {
|
||||
case 0: return NULL;
|
||||
case 2: return "ARC Sensor & Control IP Subsystem";
|
||||
case 3: return "ARC Data Fusion IP Subsystem";
|
||||
case 4: return "ARC Secure Subsystem";
|
||||
default: return "Unknown subsystem";
|
||||
};
|
||||
}
|
||||
|
||||
__weak int print_cpuinfo(void)
|
||||
{
|
||||
printf("CPU: %s\n", decode_identity());
|
||||
const char *subsys_name = decode_subsystem();
|
||||
char mhz[8];
|
||||
|
||||
printf("CPU: %s at %s MHz\n", decode_identity(),
|
||||
strmhz(mhz, gd->cpu_clk));
|
||||
|
||||
if (subsys_name)
|
||||
printf("Subsys:%s\n", subsys_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_DISPLAY_CPUINFO */
|
||||
|
Loading…
Reference in New Issue
Block a user