* [PATCH] hexagon: add hwcap
@ 2026-09-07 0:07 Brian Cain
0 siblings, 0 replies; only message in thread
From: Brian Cain @ 2026-09-07 0:07 UTC (permalink / raw)
To: linux-hexagon; +Cc: sid.manning, marco.liebel, pierrick.bouvier, Brian Cain
Provide hwcap interface for userspace programs to discover the Hexagon CPU
capabilities.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
arch/hexagon/include/asm/elf.h | 3 +-
arch/hexagon/include/asm/hexagon_vm.h | 58 +++++++++++++++
arch/hexagon/include/asm/hwcap.h | 25 +++++++
arch/hexagon/include/uapi/asm/hwcap.h | 58 +++++++++++++++
arch/hexagon/kernel/setup.c | 100 ++++++++++++++++++++++++++
arch/hexagon/kernel/vm_ops.S | 4 ++
6 files changed, 247 insertions(+), 1 deletion(-)
create mode 100644 arch/hexagon/include/asm/hwcap.h
create mode 100644 arch/hexagon/include/uapi/asm/hwcap.h
diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h
index 5bfdd9b147fd..127e750613bd 100644
--- a/arch/hexagon/include/asm/elf.h
+++ b/arch/hexagon/include/asm/elf.h
@@ -11,6 +11,7 @@
#include <asm/ptrace.h>
#include <asm/user.h>
#include <linux/elf-em.h>
+#include <asm/hwcap.h>
struct elf32_hdr;
@@ -198,7 +199,7 @@ do { \
* This yields a mask that user programs can use to figure out what
* instruction set this cpu supports.
*/
-#define ELF_HWCAP (0)
+#define ELF_HWCAP (elf_hwcap)
/*
* This yields a string that ld.so will use to load implementation
diff --git a/arch/hexagon/include/asm/hexagon_vm.h b/arch/hexagon/include/asm/hexagon_vm.h
index 9aa2493fe786..185f50618040 100644
--- a/arch/hexagon/include/asm/hexagon_vm.h
+++ b/arch/hexagon/include/asm/hexagon_vm.h
@@ -38,6 +38,7 @@
#define HVM_TRAP1_VMSETREGS 21
#define HVM_TRAP1_VMGETREGS 22
#define HVM_TRAP1_VMTIMEROP 24
+#define HVM_TRAP1_VMGETINFO 26
#ifndef __ASSEMBLY__
@@ -65,6 +66,62 @@ enum VM_INT_OPS {
hvmi_clear
};
+enum VM_INFO_TYPE {
+ vm_info_build_id,
+ vm_info_boot_flags,
+ vm_info_stlb,
+ vm_info_syscfg,
+ vm_info_livelock,
+ vm_info_rev,
+ vm_info_ssbase,
+ vm_info_tlb_free,
+ vm_info_tlb_size,
+ vm_info_physaddr,
+ vm_info_tcm_base,
+ vm_info_l2mem_size,
+ vm_info_tcm_size,
+ vm_info_h2k_pgsize,
+ vm_info_h2k_npages,
+ vm_info_l2vic_base,
+ vm_info_timer_base,
+ vm_info_timer_int,
+ vm_info_error,
+ vm_info_hthreads,
+ vm_info_l2tag_size,
+ vm_info_l2cfg_base,
+ vm_info_clade_base,
+ vm_info_cfgbase,
+ vm_info_hvx_vlength,
+};
+
+struct vm_rev {
+ union {
+ unsigned long raw;
+ struct {
+ unsigned long isa:8;
+ unsigned long l2tags:4;
+ unsigned long l2size:4;
+ unsigned long layer:4;
+ unsigned long unused:4;
+ unsigned long metal:8;
+ };
+ };
+};
+
+struct vm_boot_flags {
+ union {
+ unsigned long raw;
+ struct {
+ unsigned long use_tcm:1;
+ unsigned long have_hvx:1;
+ unsigned long have_sample:1;
+ unsigned long ext_ok:1;
+ unsigned long have_dma:1;
+ unsigned long have_hmx:1;
+ };
+ };
+};
+
extern void _K_VM_event_vector(void);
void __vmrte(void);
@@ -82,6 +139,7 @@ void __vmstop(void);
long __vmwait(void);
void __vmyield(void);
long __vmvpid(void);
+unsigned long __vmgetinfo(unsigned long);
static inline long __vmcache_ickill(void)
{
diff --git a/arch/hexagon/include/asm/hwcap.h b/arch/hexagon/include/asm/hwcap.h
new file mode 100644
index 000000000000..6bfbcec66d31
--- /dev/null
+++ b/arch/hexagon/include/asm/hwcap.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Hexagon hardware capability definitions
+ *
+ * Copyright Qualcomm Technologies, Inc. and its subsidiaries
+ */
+
+#ifndef __ASM_HEXAGON_HWCAP_H
+#define __ASM_HEXAGON_HWCAP_H
+
+#include <uapi/asm/hwcap.h>
+
+/* Kernel-internal definitions: ISA versions are used directly from UAPI */
+
+#ifndef __ASSEMBLER__
+/*
+ * This yields a mask that user programs can use to figure out what
+ * instruction set this cpu supports.
+ */
+#define ELF_HWCAP (elf_hwcap)
+
+extern unsigned long elf_hwcap;
+#endif
+
+#endif /* __ASM_HEXAGON_HWCAP_H */
diff --git a/arch/hexagon/include/uapi/asm/hwcap.h b/arch/hexagon/include/uapi/asm/hwcap.h
new file mode 100644
index 000000000000..60963257bc6f
--- /dev/null
+++ b/arch/hexagon/include/uapi/asm/hwcap.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Hexagon hardware capability definitions - User API
+ *
+ * Copyright Qualcomm Technologies, Inc. and its subsidiaries
+ */
+
+#ifndef _UAPI__ASM_HEXAGON_HWCAP_H
+#define _UAPI__ASM_HEXAGON_HWCAP_H
+
+/*
+ * HWCAP flags - for AT_HWCAP
+ *
+ * ISA Version Encoding:
+ * Bits 0-6 encode the ISA version as enumeration values
+ */
+
+/* ISA version encoding */
+#define HWCAP_HEXAGON_ISA_MASK 0x7F /* ISA version mask */
+
+/* ISA version enumeration values */
+#define HWCAP_HEXAGON_ISA_V2 1 /* Hexagon V2 */
+#define HWCAP_HEXAGON_ISA_V3 2 /* Hexagon V3 */
+#define HWCAP_HEXAGON_ISA_V4 3 /* Hexagon V4 */
+#define HWCAP_HEXAGON_ISA_V5 4 /* Hexagon V5 */
+#define HWCAP_HEXAGON_ISA_V55 5 /* Hexagon V55 */
+#define HWCAP_HEXAGON_ISA_V60 6 /* Hexagon V60 */
+#define HWCAP_HEXAGON_ISA_V62 7 /* Hexagon V62 */
+#define HWCAP_HEXAGON_ISA_V65 8 /* Hexagon V65 */
+#define HWCAP_HEXAGON_ISA_V66 9 /* Hexagon V66 */
+#define HWCAP_HEXAGON_ISA_V67 10 /* Hexagon V67 */
+#define HWCAP_HEXAGON_ISA_V68 11 /* Hexagon V68 */
+#define HWCAP_HEXAGON_ISA_V69 12 /* Hexagon V69 */
+#define HWCAP_HEXAGON_ISA_V71 13 /* Hexagon V71 */
+#define HWCAP_HEXAGON_ISA_V73 14 /* Hexagon V73 */
+#define HWCAP_HEXAGON_ISA_V79 15 /* Hexagon V79 */
+#define HWCAP_HEXAGON_ISA_V81 16 /* Hexagon V81 */
+
+/* Essential feature flags */
+#define HWCAP_HEXAGON_HVX (1 << 7) /* HVX (Hexagon Vector eXtensions) */
+#define HWCAP_HEXAGON_CABAC (1 << 8) /* CABAC acceleration */
+#define HWCAP_HEXAGON_HVX_LENGTH_128B (1 << 9) /* HVX 128-byte vector length */
+#define HWCAP_HEXAGON_HVX_IEEE_FP (1 << 10) /* HVX IEEE floating point */
+#define HWCAP_HEXAGON_AUDIO (1 << 11) /* Audio ISA extensions */
+#define HWCAP_HEXAGON_HMX (1 << 12) /* HMX matrix extensions */
+
+/* Bits 13-31 reserved for future use */
+
+/* Utility macros for userspace applications */
+#define HWCAP_HEXAGON_GET_ISA(hwcap) ((hwcap) & HWCAP_HEXAGON_ISA_MASK)
+#define HWCAP_HEXAGON_IS_ISA(hwcap, version) (HWCAP_HEXAGON_GET_ISA(hwcap) == (version))
+#define HWCAP_HEXAGON_HAS_ISA(hwcap, version) (HWCAP_HEXAGON_GET_ISA(hwcap) >= (version))
+
+/*
+ * HWCAP2 is not currently used by Hexagon.
+ */
+
+#endif /* _UAPI__ASM_HEXAGON_HWCAP_H */
diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c
index 621674e86232..99ff43bc895f 100644
--- a/arch/hexagon/kernel/setup.c
+++ b/arch/hexagon/kernel/setup.c
@@ -20,6 +20,11 @@
#include <asm/hexagon_vm.h>
#include <asm/vm_mmu.h>
#include <asm/time.h>
+#include <asm/hwcap.h>
+
+unsigned long elf_hwcap __read_mostly;
+
+EXPORT_SYMBOL_GPL(elf_hwcap);
char cmd_line[COMMAND_LINE_SIZE];
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
@@ -31,6 +36,100 @@ void calibrate_delay(void)
loops_per_jiffy = thread_freq_mhz * 1000000 / HZ;
}
+/*
+ * populate hardware capabilities using vmgetinfo
+ */
+static void __init setup_hwcap(void)
+{
+ struct vm_rev rev;
+ struct vm_boot_flags boot_flags;
+ unsigned long hvx_vlength;
+ unsigned int isa;
+
+ elf_hwcap = 0;
+
+ /* Get revision information for ISA version */
+ rev.raw = __vmgetinfo(vm_info_rev);
+ boot_flags.raw = __vmgetinfo(vm_info_boot_flags);
+
+ isa = ((rev.isa >> 4) & 0xf) * 10 + (rev.isa & 0xf);
+
+ switch (isa) {
+ case 81:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V81;
+ break;
+ case 79:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V79;
+ break;
+ case 73:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V73;
+ break;
+ case 71:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V71;
+ break;
+ case 69:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V69;
+ break;
+ case 68:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V68;
+ break;
+ case 67:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V67;
+ break;
+ case 66:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V66;
+ break;
+ case 65:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V65;
+ break;
+ case 62:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V62;
+ break;
+ case 60:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V60;
+ break;
+ case 55:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V55;
+ break;
+ case 5:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V5;
+ break;
+ case 4:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V4;
+ break;
+ case 3:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V3;
+ break;
+ case 2:
+ elf_hwcap |= HWCAP_HEXAGON_ISA_V2;
+ break;
+ default:
+ /* Unknown ISA version - leave ISA field as 0 */
+ break;
+ }
+
+ /* Check for HVX support */
+ hvx_vlength = __vmgetinfo(vm_info_hvx_vlength);
+ if (hvx_vlength) {
+ elf_hwcap |= HWCAP_HEXAGON_HVX;
+
+ if (hvx_vlength >= 128)
+ elf_hwcap |= HWCAP_HEXAGON_HVX_LENGTH_128B;
+ }
+ if (boot_flags.have_hmx)
+ elf_hwcap |= HWCAP_HEXAGON_HMX;
+
+ printk(KERN_INFO "Hexagon hwcap: 0x%08lx (v%u%s%s%s%s%s%s)\n",
+ elf_hwcap,
+ isa,
+ (elf_hwcap & HWCAP_HEXAGON_HVX) ? ", HVX" : "",
+ (elf_hwcap & HWCAP_HEXAGON_HVX_LENGTH_128B) ? ", HVX-128B" : "",
+ (elf_hwcap & HWCAP_HEXAGON_HVX_IEEE_FP) ? ", HVX-IEEE-FP" : "",
+ (elf_hwcap & HWCAP_HEXAGON_AUDIO) ? ", Audio" : "",
+ (elf_hwcap & HWCAP_HEXAGON_CABAC) ? ", CABAC" : "",
+ (elf_hwcap & HWCAP_HEXAGON_HMX) ? ", HMX" : "");
+}
+
/*
* setup_arch - high level architectural setup routine
* @cmdline_p: pointer to pointer to command-line arguments
@@ -55,6 +154,7 @@ void __init setup_arch(char **cmdline_p)
printk(KERN_INFO "PHYS_OFFSET=0x%08lx\n", PHYS_OFFSET);
+ setup_hwcap();
/*
* Simulator has a few differences from the hardware.
* For now, check uninitialized-but-mapped memory
diff --git a/arch/hexagon/kernel/vm_ops.S b/arch/hexagon/kernel/vm_ops.S
index f61c04d485f6..7bf32c55e050 100644
--- a/arch/hexagon/kernel/vm_ops.S
+++ b/arch/hexagon/kernel/vm_ops.S
@@ -25,6 +25,10 @@ ENTRY(__vmsetvec)
trap1(#HVM_TRAP1_VMSETVEC);
jumpr R31;
+ENTRY(__vmgetinfo)
+ trap1(#HVM_TRAP1_VMGETINFO);
+ jumpr R31;
+
ENTRY(__vmsetie)
trap1(#HVM_TRAP1_VMSETIE);
jumpr R31;
--
2.34.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-07 0:07 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-07 0:07 [PATCH] hexagon: add hwcap Brian Cain
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox