add lib/classtypes.c lib/cputypes.c include/linux/cputypes.h

This commit is contained in:
luck 2023-08-25 16:02:50 +08:00
parent c07b66d8c4
commit dd4c2a2b83
6 changed files with 368 additions and 7 deletions

View File

@ -41,7 +41,7 @@
(((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT)
#define MIDR_CPU_MODEL(imp, partnum) \
((_AT(u32, imp) << MIDR_IMPLEMENTOR_SHIFT) | \
(((imp) << MIDR_IMPLEMENTOR_SHIFT) | \
(0xf << MIDR_ARCHITECTURE_SHIFT) | \
((partnum) << MIDR_PARTNUM_SHIFT))
@ -54,13 +54,14 @@
#define ARM_CPU_IMP_ARM 0x41
#define ARM_CPU_IMP_APM 0x50
#define ARM_CPU_IMP_CAVIUM 0x43
#define ARM_CPU_IMP_PHYTIUM 0x70
#define ARM_CPU_IMP_BRCM 0x42
#define ARM_CPU_IMP_QCOM 0x51
#define ARM_CPU_IMP_NVIDIA 0x4E
#define ARM_CPU_IMP_FUJITSU 0x46
#define ARM_CPU_IMP_HISI 0x48
#define ARM_CPU_IMP_APPLE 0x61
#define ARM_CPU_IMP_AMPERE 0xC0
#define ARM_CPU_PART_AEM_V8 0xD0F
#define ARM_CPU_PART_FOUNDATION 0xD00
@ -85,6 +86,11 @@
#define ARM_CPU_PART_CORTEX_A78C 0xD4B
#define APM_CPU_PART_POTENZA 0x000
#define PHYTIUM_CPU_PART_1500A 0X660
#define PHYTIUM_CPU_PART_2000AHK 0X661
#define PHYTIUM_CPU_PART_2000PLUS 0X662
#define PHYTIUM_CPU_PART_2004 0X663
#define PHYTIUM_CPU_PART_2500 0X663
#define CAVIUM_CPU_PART_THUNDERX 0x0A1
#define CAVIUM_CPU_PART_THUNDERX_81XX 0x0A2
@ -106,6 +112,7 @@
#define NVIDIA_CPU_PART_DENVER 0x003
#define NVIDIA_CPU_PART_CARMEL 0x004
#define PHYTIUM_CPU_PART_FTC662 0x662
#define FUJITSU_CPU_PART_A64FX 0x001
#define HISI_CPU_PART_TSV110 0xD01
@ -113,13 +120,16 @@
#define APPLE_CPU_PART_M1_ICESTORM 0x022
#define APPLE_CPU_PART_M1_FIRESTORM 0x023
#define AMPERE_CPU_PART_AMPERE1 0xAC3
#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
#define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73)
#define MIDR_CORTEX_A75 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A75)
#define MIDR_FT_1500A MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_1500A)
#define MIDR_FT_2000AHK MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_2000AHK)
#define MIDR_FT_2000PLUS MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_2000PLUS)
#define MIDR_FT_2004 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_2004)
#define MIDR_FT_2500 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_2500)
#define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35)
#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
@ -150,11 +160,11 @@
#define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER)
#define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER)
#define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL)
#define MIDR_PHYTIUM_FT2000PLUS MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_FTC662)
#define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX)
#define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110)
#define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM)
#define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM)
#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
/* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
#define MIDR_FUJITSU_ERRATUM_010001 MIDR_FUJITSU_A64FX

24
include/linux/cputypes.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef _LIB_CPU_TYPE_H
#define _LIB_CPU_TYPE_H
// if arch is arm64 then need to judge cpu type, otherwise return false
#ifdef CONFIG_ARM64
#include <asm/cputype.h>
#define MACHINE_TYPE_FUN_DEFS(cpu) \
bool cpu_is_##cpu(void);
#else
#define MACHINE_TYPE_FUN_DEFS(cpu) \
static bool cpu_is_##cpu(void) { return false; }
#endif
MACHINE_TYPE_FUN_DEFS(ft_d2000)
MACHINE_TYPE_FUN_DEFS(phytium)
MACHINE_TYPE_FUN_DEFS(ft2004)
MACHINE_TYPE_FUN_DEFS(kunpeng)
MACHINE_TYPE_FUN_DEFS(kunpeng_3211k)
MACHINE_TYPE_FUN_DEFS(hisi)
MACHINE_TYPE_FUN_DEFS(pangu)
MACHINE_TYPE_FUN_DEFS(kunpeng920_series)
MACHINE_TYPE_FUN_DEFS(kunpeng_920l)
MACHINE_TYPE_FUN_DEFS(kunpeng_920s)
#endif

View File

@ -381,7 +381,7 @@ config GENERIC_ALLOCATOR
#
config REED_SOLOMON
tristate
config REED_SOLOMON_ENC8
bool
@ -488,6 +488,7 @@ config ASSOCIATIVE_ARRAY
config HAS_IOMEM
bool
depends on !NO_IOMEM
select GENERIC_IO
default y
config HAS_IOPORT_MAP

View File

@ -48,7 +48,8 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
bsearch.o find_bit.o llist.o memweight.o kfifo.o \
percpu-refcount.o rhashtable.o \
once.o refcount.o usercopy.o errseq.o bucket_locks.o \
generic-radix-tree.o
generic-radix-tree.o classtypes.o
obj-$(CONFIG_ARM64) += cputypes.o
obj-$(CONFIG_STRING_SELFTEST) += test_string.o
obj-y += string_helpers.o
obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o

151
lib/classtypes.c Normal file
View File

@ -0,0 +1,151 @@
#include <linux/dmi.h>
#include <linux/string.h>
#include <asm/dmi.h>
#include <linux/classtypes.h>
static char *cpu_name = NULL;
static bool get_cpu_flag = false;
static void get_cpuname_by_dmi(const struct dmi_header *dm, void *data)
{
const char *bp;
const u8 *nsp;
char *sm ;
char s;
if(!dm)
return;
if (dm->type != 4)
return;
bp = ((u8 *) dm) + dm->length;
sm = (char *)dm;
s = sm[0x10];
if (s) {
while (--s > 0 && *bp)
bp += strlen(bp) + 1;
/* Strings containing only spaces are considered empty */
nsp = bp;
while (*nsp == ' ')
nsp++;
if (*nsp != '\0'){
cpu_name = dmi_alloc(strlen(bp) + 1);
if (cpu_name != NULL)
strcpy(cpu_name, bp);
get_cpu_flag = true;
return;
}
}
return;
}
char *get_cpu_name(void)
{
if(!get_cpu_flag)
dmi_walk(get_cpuname_by_dmi, cpu_name);
if(cpu_name == NULL) {
/* Some BIOS don't support getting CPU name from DMI */
return "UNKNOWN-CPU";
}
return cpu_name;
}
EXPORT_SYMBOL(get_cpu_name);
static unsigned long chassis_type = 0;
unsigned long get_chassis_types(void)
{
const char *chassis_type_str = NULL;
if (chassis_type)
return chassis_type;
chassis_type_str = dmi_get_system_info(DMI_CHASSIS_TYPE);
if (!chassis_type_str)
return 0;
if (kstrtoul(chassis_type_str, 10, &chassis_type) != 0)
return 0;
return chassis_type;
}
EXPORT_SYMBOL(get_chassis_types);
bool chassis_types_is_laptop(void)
{
unsigned long type;
type = get_chassis_types();
switch (type) {
case 0x09: /* Laptop */
case 0x0A: /* Notebook */
return true;
}
return false;
}
EXPORT_SYMBOL(chassis_types_is_laptop);
bool chassis_types_is_desktop(void)
{
unsigned long type;
type = get_chassis_types();
switch (type) {
case 0x03: /* Desktop */
case 0x04: /* Low Profile Desktop */
case 0x05: /* Pizza Box */
case 0x06: /* Mini Tower */
case 0x07: /* Tower */
case 0x10: /* Lunch Box */
return true;
}
return false;
}
EXPORT_SYMBOL(chassis_types_is_desktop);
bool chassis_types_is_server(void)
{
unsigned long type;
type = get_chassis_types();
switch (type) {
case 0x11: /* Main Server Chassis */
return true;
}
return false;
}
EXPORT_SYMBOL(chassis_types_is_server);
bool chassis_types_is_allinone(void)
{
unsigned long type;
type = get_chassis_types();
switch (type) {
case 0x0D: // All in One
return true;
}
return false;
}
EXPORT_SYMBOL(chassis_types_is_allinone);
bool os_run_evn_is_virt(void)
{
if (strncmp(get_cpu_name(), "virt",4) == 0) {
return true;
}
return false;
}
EXPORT_SYMBOL(os_run_evn_is_virt);

174
lib/cputypes.c Normal file
View File

@ -0,0 +1,174 @@
#include <linux/dmi.h>
#include <linux/string.h>
#include <asm/dmi.h>
#include <linux/cputypes.h>
#include <linux/classtypes.h>
static char core_count = 0;
static u32 huawei_cpu_type = 0;
/* Callback function used to retrieve the core count from DMI */
static void get_core_count_by_dmi(const struct dmi_header *dm, void *cpu_count)
{
const u8 *dmi_data = (const u8 *)dm;
if (dm->type == 4 && dm->length >= 0x28) {
*(u8 *)cpu_count = *(const u8 *)(dmi_data + 0x23);
}
}
/* Look up the core count in DMI */
static u8 get_core_count(void)
{
if (0 == core_count)
dmi_walk(get_core_count_by_dmi, &core_count);
return core_count;
}
int cpuid_phytium_flag = -1;
static bool cpuid_is_phytium(void)
{
int cpu_model;
if (cpuid_phytium_flag != -1)
return cpuid_phytium_flag;
cpu_model = read_cpuid_id() & MIDR_CPU_MODEL_MASK;
if((cpu_model == MIDR_FT_2500) || (cpu_model == MIDR_PHYTIUM_FT2000PLUS)){
cpuid_phytium_flag = true;
} else {
cpuid_phytium_flag = false;
}
return cpuid_phytium_flag;
}
bool cpu_is_ft_d2000(void)
{
return cpuid_is_phytium() && (get_core_count() == 8);
}
EXPORT_SYMBOL(cpu_is_ft_d2000);
bool cpu_is_phytium(void)
{
return cpuid_is_phytium();
}
EXPORT_SYMBOL(cpu_is_phytium);
bool cpu_is_ft2004(void)
{
if ((strncmp(get_cpu_name(), "FT2004", 6) == 0) ||
(strncmp(get_cpu_name(), "FT2000A",7) == 0) ||
(strncmp(get_cpu_name(), "FT-2000/4",9) == 0)) {
return true;
}
return false;
}
EXPORT_SYMBOL(cpu_is_ft2004);
int cpuid_kunpeng_flag = -1;
bool cpuid_is_kunpeng(void)
{
int cpu_model;
if (cpuid_kunpeng_flag != -1)
return cpuid_kunpeng_flag;
cpu_model = read_cpuid_id() & MIDR_CPU_MODEL_MASK;
if(cpu_model == MIDR_HISI_TSV110) {
cpuid_kunpeng_flag = true;
} else {
cpuid_kunpeng_flag = false;
}
return cpuid_kunpeng_flag;
}
EXPORT_SYMBOL(cpuid_is_kunpeng);
/* For Pangu CPU kunpeng920 3211k */
bool cpu_is_kunpeng_3211k(void)
{
if (strncmp(get_cpu_name(),
"HUAWEI Kunpeng920 3211K", 32) == 0)
return true;
return false;
}
EXPORT_SYMBOL(cpu_is_kunpeng_3211k);
bool cpu_is_hisi(void)
{
if (strncmp(get_cpu_name(), "HUAWEI",6) == 0) {
return true;
}
return false;
}
EXPORT_SYMBOL(cpu_is_hisi);
/* For CPU pangu */
bool cpu_is_pangu(void)
{
return cpu_is_kunpeng_3211k();
}
EXPORT_SYMBOL(cpu_is_pangu);
bool cpu_is_kunpeng920_series(void)
{
if (strncmp(get_cpu_name(), "HUAWEI Kunpeng 920", 18) == 0) {
return true;
}
return false;
}
EXPORT_SYMBOL(cpu_is_kunpeng920_series);
/* kunpeng920 cpu type register */
static u32 get_920_type_reg(void)
{
#define KUNPENG_920_CPU_TYPE_REG_ADDR 0x9038e200
static void __iomem *ioaddr = NULL;
u32 cpu_type = 0;
if (ioaddr) {
return huawei_cpu_type;
}
ioaddr = ioremap(KUNPENG_920_CPU_TYPE_REG_ADDR, 0x100);
if(ioaddr == NULL) {
printk(KERN_INFO "get_920_type_reg ioremap return NULL \n\r");
return -1;
}
cpu_type =readl(ioaddr + 0x24);
huawei_cpu_type = (cpu_type >> 8) & 0xf;
return huawei_cpu_type;
}
/* For CPU kunpeng920L */
bool cpu_is_kunpeng_920l(void)
{
if (!cpu_is_kunpeng920_series())
return false;
if ((get_core_count() <= 12) && (get_920_type_reg() == 0x1))
return true;
else
return false;
}
EXPORT_SYMBOL(cpu_is_kunpeng_920l);
/* For CPU kunpeng920s */
bool cpu_is_kunpeng_920s(void)
{
if (!cpu_is_kunpeng920_series())
return false;
if (cpu_is_pangu() || cpu_is_kunpeng_920l())
return false;
return true;
}
EXPORT_SYMBOL(cpu_is_kunpeng_920s);