Linux Hexagon architecture development
 help / color / mirror / Atom feed
* [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