Use ELF_BASE_PLATFORM to pass ISA level
authorYunQiang Su <syq@debian.org>
Sat, 7 Mar 2020 02:39:45 +0000 (10:39 +0800)
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>
Thu, 19 Mar 2020 12:09:33 +0000 (13:09 +0100)
Some userland application/program runtime/dynamic loaded need to
know about the current ISA level to use the best runtime.
While kernel doesn't provides this info.

ELF_PLATFORM only provides some info about the CPU, with very few info,
for example, the value is "mips" for both 24Kc and P6600.

Currently ELF_BASE_PLATFORM is not used by MIPS (only by powerpc).
So we cant set its value as:
  mips2, mips3, mips4, mips5,
  mips32, mips32r2, mips32r6
  mips64, mips64r2, mips64r6
Then in userland, we can get it by:
  getauxval(AT_BASE_PLATFORM)

The only problem is that it seems has different defination than ppc:
  on ppc, it is the mircoarchitecture
while now we use it as ISA level on MIPS.

Signed-off-by: YunQiang Su <syq@debian.org>
Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
arch/mips/include/asm/elf.h
arch/mips/kernel/cpu-probe.c

index f8f44b1a6cbb491e4125137a2642d3cf9faaebb5..5aa29ced69709a3eaf85bcbec21925b91f240a55 100644 (file)
@@ -445,6 +445,9 @@ extern unsigned int elf_hwcap;
 #define ELF_PLATFORM  __elf_platform
 extern const char *__elf_platform;
 
+#define ELF_BASE_PLATFORM  __elf_base_platform
+extern const char *__elf_base_platform;
+
 /*
  * See comments in asm-alpha/elf.h, this is the same thing
  * on the MIPS.
index 6ab6b03d35ba7c0b58a4027830aaa2d629f30dfb..f21a2304401f92ef076d83f0533a0eb13118d382 100644 (file)
@@ -513,6 +513,13 @@ static inline void set_elf_platform(int cpu, const char *plat)
                __elf_platform = plat;
 }
 
+static inline void set_elf_base_platform(const char *plat)
+{
+       if (__elf_base_platform == NULL) {
+               __elf_base_platform = plat;
+       }
+}
+
 static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
 {
 #ifdef __NEED_VMBITS_PROBE
@@ -527,36 +534,46 @@ static void set_isa(struct cpuinfo_mips *c, unsigned int isa)
        switch (isa) {
        case MIPS_CPU_ISA_M64R2:
                c->isa_level |= MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2;
+               set_elf_base_platform("mips64r2");
                /* fall through */
        case MIPS_CPU_ISA_M64R1:
                c->isa_level |= MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1;
+               set_elf_base_platform("mips64");
                /* fall through */
        case MIPS_CPU_ISA_V:
                c->isa_level |= MIPS_CPU_ISA_V;
+               set_elf_base_platform("mips5");
                /* fall through */
        case MIPS_CPU_ISA_IV:
                c->isa_level |= MIPS_CPU_ISA_IV;
+               set_elf_base_platform("mips4");
                /* fall through */
        case MIPS_CPU_ISA_III:
                c->isa_level |= MIPS_CPU_ISA_II | MIPS_CPU_ISA_III;
+               set_elf_base_platform("mips3");
                break;
 
        /* R6 incompatible with everything else */
        case MIPS_CPU_ISA_M64R6:
                c->isa_level |= MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6;
+               set_elf_base_platform("mips64r6");
                /* fall through */
        case MIPS_CPU_ISA_M32R6:
                c->isa_level |= MIPS_CPU_ISA_M32R6;
+               set_elf_base_platform("mips32r6");
                /* Break here so we don't add incompatible ISAs */
                break;
        case MIPS_CPU_ISA_M32R2:
                c->isa_level |= MIPS_CPU_ISA_M32R2;
+               set_elf_base_platform("mips32r2");
                /* fall through */
        case MIPS_CPU_ISA_M32R1:
                c->isa_level |= MIPS_CPU_ISA_M32R1;
+               set_elf_base_platform("mips32");
                /* fall through */
        case MIPS_CPU_ISA_II:
                c->isa_level |= MIPS_CPU_ISA_II;
+               set_elf_base_platform("mips2");
                break;
        }
 }
@@ -2113,6 +2130,7 @@ EXPORT_SYMBOL(__ua_limit);
 
 const char *__cpu_name[NR_CPUS];
 const char *__elf_platform;
+const char *__elf_base_platform;
 
 void cpu_probe(void)
 {