aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeifei Wang <wangfeifei@hygon.cn>2024-08-19 14:57:54 +0800
committerH.J. Lu <hjl.tools@gmail.com>2024-08-26 10:01:58 -0700
commitd14aecbffc032c97d86fdbfdcb7991d1a55e8399 (patch)
tree0249dafb86d71c376eb1790ecbcd53340c5bd8eb
parentx86: Add new architecture type for Hygon processors (diff)
downloadglibc-d14aecbffc032c97d86fdbfdcb7991d1a55e8399.tar.xz
glibc-d14aecbffc032c97d86fdbfdcb7991d1a55e8399.zip
x86: Add cache information support for Hygon processors
Add hygon branch in dl_init_cacheinfo function to initialize cache size variables for hygon processors. In the meanwhile, add handle_hygon() function to get cache information. Signed-off-by: Feifei Wang <wangfeifei@hygon.cn> Reviewed-by: Jing Li <lijing@hygon.cn> Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
-rw-r--r--sysdeps/x86/dl-cacheinfo.h60
1 files changed, 60 insertions, 0 deletions
diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
index 82e4aa5c19..8f4fe98d88 100644
--- a/sysdeps/x86/dl-cacheinfo.h
+++ b/sysdeps/x86/dl-cacheinfo.h
@@ -567,6 +567,48 @@ handle_zhaoxin (int name)
return 0;
}
+static long int __attribute__ ((noinline))
+handle_hygon (int name)
+{
+ unsigned int eax;
+ unsigned int ebx;
+ unsigned int ecx;
+ unsigned int edx;
+ unsigned int count = 0x1;
+
+ if (name >= _SC_LEVEL3_CACHE_SIZE)
+ count = 0x3;
+ else if (name >= _SC_LEVEL2_CACHE_SIZE)
+ count = 0x2;
+ else if (name >= _SC_LEVEL1_DCACHE_SIZE)
+ count = 0x0;
+
+ /* Use __cpuid__ '0x8000_001D' to compute cache details. */
+ __cpuid_count (0x8000001D, count, eax, ebx, ecx, edx);
+
+ switch (name)
+ {
+ case _SC_LEVEL1_ICACHE_ASSOC:
+ case _SC_LEVEL1_DCACHE_ASSOC:
+ case _SC_LEVEL2_CACHE_ASSOC:
+ case _SC_LEVEL3_CACHE_ASSOC:
+ return ((ebx >> 22) & 0x3ff) + 1;
+ case _SC_LEVEL1_ICACHE_LINESIZE:
+ case _SC_LEVEL1_DCACHE_LINESIZE:
+ case _SC_LEVEL2_CACHE_LINESIZE:
+ case _SC_LEVEL3_CACHE_LINESIZE:
+ return (ebx & 0xfff) + 1;
+ case _SC_LEVEL1_ICACHE_SIZE:
+ case _SC_LEVEL1_DCACHE_SIZE:
+ case _SC_LEVEL2_CACHE_SIZE:
+ case _SC_LEVEL3_CACHE_SIZE:
+ return (((ebx >> 22) & 0x3ff) + 1) * ((ebx & 0xfff) + 1) * (ecx + 1);
+ default:
+ __builtin_unreachable ();
+ }
+ return -1;
+}
+
static void
get_common_cache_info (long int *shared_ptr, long int * shared_per_thread_ptr, unsigned int *threads_ptr,
long int core)
@@ -889,6 +931,24 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
shared_per_thread = shared;
}
+ else if (cpu_features->basic.kind == arch_kind_hygon)
+ {
+ data = handle_hygon (_SC_LEVEL1_DCACHE_SIZE);
+ shared = handle_hygon (_SC_LEVEL3_CACHE_SIZE);
+ shared_per_thread = shared;
+
+ level1_icache_size = handle_hygon (_SC_LEVEL1_ICACHE_SIZE);
+ level1_icache_linesize = handle_hygon (_SC_LEVEL1_ICACHE_LINESIZE);
+ level1_dcache_size = data;
+ level1_dcache_assoc = handle_hygon (_SC_LEVEL1_DCACHE_ASSOC);
+ level1_dcache_linesize = handle_hygon (_SC_LEVEL1_DCACHE_LINESIZE);
+ level2_cache_size = handle_hygon (_SC_LEVEL2_CACHE_SIZE);;
+ level2_cache_assoc = handle_hygon (_SC_LEVEL2_CACHE_ASSOC);
+ level2_cache_linesize = handle_hygon (_SC_LEVEL2_CACHE_LINESIZE);
+ level3_cache_size = shared;
+ level3_cache_assoc = handle_hygon (_SC_LEVEL3_CACHE_ASSOC);
+ level3_cache_linesize = handle_hygon (_SC_LEVEL3_CACHE_LINESIZE);
+ }
cpu_features->level1_icache_size = level1_icache_size;
cpu_features->level1_icache_linesize = level1_icache_linesize;