[v2,2/3] x86: Add cache information support for Hygon processors

Message ID 1724050675-17136-3-git-send-email-wangfeifei@hygon.cn
State Committed
Commit d14aecbffc032c97d86fdbfdcb7991d1a55e8399
Delegated to: H.J. Lu
Headers
Series x86: Add support for Hygon processors |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed

Commit Message

Feifei Wang Aug. 19, 2024, 6:57 a.m. UTC
  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>
---
 sysdeps/x86/dl-cacheinfo.h | 60 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)
  

Comments

H.J. Lu Aug. 24, 2024, 8:31 p.m. UTC | #1
On Sun, Aug 18, 2024 at 11:58 PM Feifei Wang <wangfeifei@hygon.cn> wrote:
>
> 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>
> ---
>  sysdeps/x86/dl-cacheinfo.h | 60 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 60 insertions(+)
>
> 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;
> --
> 2.43.0
>

LGTM.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>

Thanks.
  

Patch

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;