Download raw body.
devel/jdk: aarch64 cpu info and hardware capablities
On Wed, 17 Dec 2025 15:58:29 +0100,
Kurt Miller <kurt@intricatesoftware.com> wrote:
>
> New version. On aarch64 the jdk wants hardware capablities and cpu
> info so it can adjust its behavior to conform to the hardware ablities.
>
> This diff uses elf_aux_info(3) for hardware capablities and if
> HWCAP_CPUID is set will use READ_SPECIALREG(midr_el1) to obtain
> the cpu info. If HWCAP_CPUID is not set it will fallback to parsing
> sysctl hw.model output to lookup the cpu info.
>
> This has been tested on Apple Mac Mini (M2 Pro, 2023) which supports
> HWCAP_CPUID and Pine64 RockPro64 v2.1 which does not support
> HWCAP_CPUID. It also corrects some deadlocks I was seeing on the
> Mac Mini in the tier1 tests.
>
> okay?
>
Tested as jdk-25 only on Qualcomm Oryon r2p1 (known as Snapdragon X Elite)
make install && FLAVOR=native_bootstrap make clean build
works.
> Index: 1.8/Makefile
> ===================================================================
> RCS file: /cvs/ports/devel/jdk/1.8/Makefile,v
> diff -u -p -u -r1.100 Makefile
> --- 1.8/Makefile 3 Nov 2025 13:37:17 -0000 1.100
> +++ 1.8/Makefile 16 Dec 2025 19:33:50 -0000
> @@ -12,6 +12,7 @@ V= ${BASE_VER}.${UPDATE_VER}.${BUILD_VE
> PKGNAME= jdk-${V}
> PKGSTEM= jdk-${BASE_VER}
> EPOCH= 0
> +REVISION= 0
>
> DIST_SUBDIR= jdk
> DISTNAME= jdk8u${UPDATE_VER}-${BUILD_VER}.${BSD_PORT_REL}
> Index: 1.8/patches/patch-hotspot_src_os_cpu_bsd_aarch64_vm_vm_version_bsd_aarch64_cpp
> ===================================================================
> RCS file: 1.8/patches/patch-hotspot_src_os_cpu_bsd_aarch64_vm_vm_version_bsd_aarch64_cpp
> diff -N 1.8/patches/patch-hotspot_src_os_cpu_bsd_aarch64_vm_vm_version_bsd_aarch64_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ 1.8/patches/patch-hotspot_src_os_cpu_bsd_aarch64_vm_vm_version_bsd_aarch64_cpp 16 Dec 2025 19:33:50 -0000
> @@ -0,0 +1,493 @@
> +Get hardware capablilites using elf_aux_info(3).
> +Detect CPU, model, variant and revision using READ_SPECIALREG
> +when HWCAP_CPUID is set, otherwise parse sysctl hw.model to
> +get needed info.
> +
> +Index: hotspot/src/os_cpu/bsd_aarch64/vm/vm_version_bsd_aarch64.cpp
> +--- hotspot/src/os_cpu/bsd_aarch64/vm/vm_version_bsd_aarch64.cpp.orig
> ++++ hotspot/src/os_cpu/bsd_aarch64/vm/vm_version_bsd_aarch64.cpp
> +@@ -27,91 +27,84 @@
> + #include "vm_version_aarch64.hpp"
> +
> + #include <machine/armreg.h>
> +-#if defined (__FreeBSD__)
> +-#include <machine/elf.h>
> ++#if defined (__FreeBSD__) || defined (__OpenBSD__)
> ++#include <sys/auxv.h>
> + #endif
> +
> +-#ifndef HWCAP_ASIMD
> +-#define HWCAP_ASIMD (1<<1)
> +-#endif
> ++#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
> ++#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
> ++#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
> ++#define CPU_REV(midr) (((midr) >> 0) & 0xf)
> +
> +-#ifndef HWCAP_AES
> +-#define HWCAP_AES (1<<3)
> +-#endif
> ++#ifdef __OpenBSD__
> ++// For older processors on OpenBSD READ_SPECIALREG is not supported.
> ++// These constants and tables allow for looking up the cpu and model.
> +
> +-#ifndef HWCAP_PMULL
> +-#define HWCAP_PMULL (1<<4)
> +-#endif
> ++#include <sys/types.h>
> ++#include <sys/sysctl.h>
> ++#include <string.h>
> ++#include <stdio.h>
> +
> +-#ifndef HWCAP_SHA1
> +-#define HWCAP_SHA1 (1<<5)
> +-#endif
> +-
> +-#ifndef HWCAP_SHA2
> +-#define HWCAP_SHA2 (1<<6)
> +-#endif
> +-
> +-#ifndef HWCAP_CRC32
> +-#define HWCAP_CRC32 (1<<7)
> +-#endif
> +-
> +-#ifndef HWCAP_ATOMICS
> +-#define HWCAP_ATOMICS (1<<8)
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_SHIFT
> +-#define ID_AA64PFR0_AdvSIMD_SHIFT 20
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD
> +-#define ID_AA64PFR0_AdvSIMD(x) ((x) & (UL(0xf) << ID_AA64PFR0_AdvSIMD_SHIFT))
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_IMPL
> +-#define ID_AA64PFR0_AdvSIMD_IMPL (UL(0x0) << ID_AA64PFR0_AdvSIMD_SHIFT)
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_HP
> +-#define ID_AA64PFR0_AdvSIMD_HP (UL(0x1) << ID_AA64PFR0_AdvSIMD_SHIFT)
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_AES_VAL
> +-#define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_SHA1_VAL
> +-#define ID_AA64ISAR0_SHA1_VAL ID_AA64ISAR0_SHA1
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_SHA2_VAL
> +-#define ID_AA64ISAR0_SHA2_VAL ID_AA64ISAR0_SHA2
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_CRC32_VAL
> +-#define ID_AA64ISAR0_CRC32_VAL ID_AA64ISAR0_CRC32
> +-#endif
> +-
> + #define CPU_IMPL_ARM 0x41
> + #define CPU_IMPL_BROADCOM 0x42
> + #define CPU_IMPL_CAVIUM 0x43
> + #define CPU_IMPL_DEC 0x44
> ++#define CPU_IMPL_FUJITSU 0x46
> ++#define CPU_IMPL_HISILICON 0x48
> + #define CPU_IMPL_INFINEON 0x49
> + #define CPU_IMPL_FREESCALE 0x4D
> + #define CPU_IMPL_NVIDIA 0x4E
> + #define CPU_IMPL_APM 0x50
> + #define CPU_IMPL_QUALCOMM 0x51
> + #define CPU_IMPL_MARVELL 0x56
> ++#define CPU_IMPL_APPLE 0x61
> + #define CPU_IMPL_INTEL 0x69
> ++#define CPU_IMPL_AMPERE 0xC0
> ++#define CPU_IMPL_MICROSOFT 0x6D
> +
> + /* ARM Part numbers */
> + #define CPU_PART_FOUNDATION 0xD00
> +-#define CPU_PART_CORTEX_A35 0xD04
> ++#define CPU_PART_CORTEX_A34 0xD02
> + #define CPU_PART_CORTEX_A53 0xD03
> ++#define CPU_PART_CORTEX_A35 0xD04
> + #define CPU_PART_CORTEX_A55 0xD05
> ++#define CPU_PART_CORTEX_A65 0xD06
> + #define CPU_PART_CORTEX_A57 0xD07
> + #define CPU_PART_CORTEX_A72 0xD08
> + #define CPU_PART_CORTEX_A73 0xD09
> + #define CPU_PART_CORTEX_A75 0xD0A
> ++#define CPU_PART_CORTEX_A76 0xD0B
> ++#define CPU_PART_NEOVERSE_N1 0xD0C
> ++#define CPU_PART_CORTEX_A77 0xD0D
> ++#define CPU_PART_CORTEX_A76AE 0xD0E
> ++#define CPU_PART_AEM_V8 0xD0F
> ++#define CPU_PART_NEOVERSE_V1 0xD40
> ++#define CPU_PART_CORTEX_A78 0xD41
> ++#define CPU_PART_CORTEX_A78AE 0xD42
> ++#define CPU_PART_CORTEX_A65AE 0xD43
> ++#define CPU_PART_CORTEX_X1 0xD44
> ++#define CPU_PART_CORTEX_A510 0xD46
> ++#define CPU_PART_CORTEX_A710 0xD47
> ++#define CPU_PART_CORTEX_X2 0xD48
> ++#define CPU_PART_NEOVERSE_N2 0xD49
> ++#define CPU_PART_NEOVERSE_E1 0xD4A
> ++#define CPU_PART_CORTEX_A78C 0xD4B
> ++#define CPU_PART_CORTEX_X1C 0xD4C
> ++#define CPU_PART_CORTEX_A715 0xD4D
> ++#define CPU_PART_CORTEX_X3 0xD4E
> ++#define CPU_PART_NEOVERSE_V2 0xD4F
> ++#define CPU_PART_CORTEX_A520 0xD80
> ++#define CPU_PART_CORTEX_A720 0xD81
> ++#define CPU_PART_CORTEX_X4 0xD82
> ++#define CPU_PART_NEOVERSE_V3AE 0xD83
> ++#define CPU_PART_NEOVERSE_V3 0xD84
> ++#define CPU_PART_CORTEX_X925 0xD85
> ++#define CPU_PART_CORTEX_A725 0xD87
> ++#define CPU_PART_C1_NANO 0xD8A
> ++#define CPU_PART_C1_PRO 0xD8B
> ++#define CPU_PART_C1_ULTRA 0xD8C
> ++#define CPU_PART_NEOVERSE_N3 0xD8E
> ++#define CPU_PART_C1_PREMIUM 0xD90
> +
> + /* Cavium Part numbers */
> + #define CPU_PART_THUNDERX 0x0A1
> +@@ -124,21 +117,35 @@
> +
> + #define CPU_REV_THUNDERX2_0 0x00
> +
> +-#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
> +-#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
> +-#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
> +-#define CPU_REV(midr) (((midr) >> 0) & 0xf)
> +-#define UL(x) UINT64_C(x)
> ++/* APM (now Ampere) Part number */
> ++#define CPU_PART_EMAG8180 0x000
> +
> +-struct cpu_desc {
> +- u_int cpu_impl;
> +- u_int cpu_part_num;
> +- u_int cpu_variant;
> +- u_int cpu_revision;
> +- const char *cpu_impl_name;
> +- const char *cpu_part_name;
> +-};
> ++/* Ampere Part numbers */
> ++#define CPU_PART_AMPERE1 0xAC3
> ++#define CPU_PART_AMPERE1A 0xAC4
> +
> ++/* Microsoft Part numbers */
> ++#define CPU_PART_AZURE_COBALT_100 0xD49
> ++
> ++/* Qualcomm */
> ++#define CPU_PART_ORYON 0x001
> ++#define CPU_PART_KRYO400_GOLD 0x804
> ++#define CPU_PART_KRYO400_SILVER 0x805
> ++
> ++/* Apple part numbers */
> ++#define CPU_PART_M1_ICESTORM 0x022
> ++#define CPU_PART_M1_FIRESTORM 0x023
> ++#define CPU_PART_M1_ICESTORM_PRO 0x024
> ++#define CPU_PART_M1_FIRESTORM_PRO 0x025
> ++#define CPU_PART_M1_ICESTORM_MAX 0x028
> ++#define CPU_PART_M1_FIRESTORM_MAX 0x029
> ++#define CPU_PART_M2_BLIZZARD 0x032
> ++#define CPU_PART_M2_AVALANCHE 0x033
> ++#define CPU_PART_M2_BLIZZARD_PRO 0x034
> ++#define CPU_PART_M2_AVALANCHE_PRO 0x035
> ++#define CPU_PART_M2_BLIZZARD_MAX 0x038
> ++#define CPU_PART_M2_AVALANCHE_MAX 0x039
> ++
> + struct cpu_parts {
> + u_int part_id;
> + const char *part_name;
> +@@ -159,130 +166,218 @@ struct cpu_implementers {
> + /*
> + * Per-implementer table of (PartNum, CPU Name) pairs.
> + */
> +-/* ARM Ltd. */
> ++/* ARM Ltd. From FreeBSD but using OpenBSD strings */
> + static const struct cpu_parts cpu_parts_arm[] = {
> ++ { CPU_PART_AEM_V8, "AEMv8" },
> + { CPU_PART_FOUNDATION, "Foundation-Model" },
> ++ { CPU_PART_CORTEX_A34, "Cortex-A34" },
> + { CPU_PART_CORTEX_A35, "Cortex-A35" },
> + { CPU_PART_CORTEX_A53, "Cortex-A53" },
> + { CPU_PART_CORTEX_A55, "Cortex-A55" },
> + { CPU_PART_CORTEX_A57, "Cortex-A57" },
> ++ { CPU_PART_CORTEX_A65, "Cortex-A65" },
> ++ { CPU_PART_CORTEX_A65AE, "Cortex-A65AE" },
> + { CPU_PART_CORTEX_A72, "Cortex-A72" },
> + { CPU_PART_CORTEX_A73, "Cortex-A73" },
> + { CPU_PART_CORTEX_A75, "Cortex-A75" },
> ++ { CPU_PART_CORTEX_A76, "Cortex-A76" },
> ++ { CPU_PART_CORTEX_A76AE, "Cortex-A76AE" },
> ++ { CPU_PART_CORTEX_A77, "Cortex-A77" },
> ++ { CPU_PART_CORTEX_A78, "Cortex-A78" },
> ++ { CPU_PART_CORTEX_A78AE, "Cortex-A78AE" },
> ++ { CPU_PART_CORTEX_A78C, "Cortex-A78C" },
> ++ { CPU_PART_CORTEX_A510, "Cortex-A510" },
> ++ { CPU_PART_CORTEX_A520, "Cortex-A520" },
> ++ { CPU_PART_CORTEX_A710, "Cortex-A710" },
> ++ { CPU_PART_CORTEX_A715, "Cortex-A715" },
> ++ { CPU_PART_CORTEX_A720, "Cortex-A720" },
> ++ { CPU_PART_CORTEX_A725, "Cortex-A725" },
> ++ { CPU_PART_CORTEX_X925, "Cortex-A925" },
> ++ { CPU_PART_CORTEX_X1C, "Cortex-X1C" },
> ++ { CPU_PART_CORTEX_X1, "Cortex-X1" },
> ++ { CPU_PART_CORTEX_X2, "Cortex-X2" },
> ++ { CPU_PART_CORTEX_X3, "Cortex-X3" },
> ++ { CPU_PART_CORTEX_X4, "Cortex-X4" },
> ++ { CPU_PART_C1_NANO, "C1-Nano" },
> ++ { CPU_PART_C1_PRO, "C1-Pro" },
> ++ { CPU_PART_C1_PREMIUM, "C1-Premium" },
> ++ { CPU_PART_C1_ULTRA, "C1-Ultra" },
> ++ { CPU_PART_NEOVERSE_E1, "Neoverse E1" },
> ++ { CPU_PART_NEOVERSE_N1, "Neoverse N1" },
> ++ { CPU_PART_NEOVERSE_N2, "Neoverse N2" },
> ++ { CPU_PART_NEOVERSE_N3, "Neoverse N3" },
> ++ { CPU_PART_NEOVERSE_V1, "Neoverse V1" },
> ++ { CPU_PART_NEOVERSE_V2, "Neoverse V2" },
> ++ { CPU_PART_NEOVERSE_V3, "Neoverse V3" },
> ++ { CPU_PART_NEOVERSE_V3AE, "Neoverse V3AE" },
> + CPU_PART_NONE,
> + };
> +-/* Cavium */
> ++
> ++/* Cavium From FreeBSD but using OpenBSD strings */
> + static const struct cpu_parts cpu_parts_cavium[] = {
> +- { CPU_PART_THUNDERX, "ThunderX" },
> +- { CPU_PART_THUNDERX2, "ThunderX2" },
> ++ { CPU_PART_THUNDERX, "ThunderX T88" },
> ++ { CPU_PART_THUNDERX_81XX, "ThunderX T81" },
> ++ { CPU_PART_THUNDERX_83XX, "ThunderX T83" },
> ++ { CPU_PART_THUNDERX2, "ThunderX2 T99" },
> + CPU_PART_NONE,
> + };
> +
> ++/* APM (now Ampere), From FreeBSD but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_apm[] = {
> ++ { CPU_PART_EMAG8180, "X-Gene" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Ampere From FreeBSD, but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_ampere[] = {
> ++ { CPU_PART_AMPERE1A, "AmpereOne AC04" },
> ++ { CPU_PART_AMPERE1, "AmpereOne" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Microsoft */
> ++static const struct cpu_parts cpu_parts_microsoft[] = {
> ++ { CPU_PART_AZURE_COBALT_100, "Azure Cobalt 100" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Qualcomm From FreeBSD & OpenBSD. */
> ++static const struct cpu_parts cpu_parts_qcom[] = {
> ++ { CPU_PART_KRYO400_GOLD, "Kryo 400 Gold" },
> ++ { CPU_PART_KRYO400_SILVER, "Kryo 400 Silver" },
> ++ { CPU_PART_ORYON, "Oryon" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Apple. From FreeBSD but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_apple[] = {
> ++ { CPU_PART_M1_ICESTORM, "Icestorm" },
> ++ { CPU_PART_M1_FIRESTORM, "Firestorm" },
> ++ { CPU_PART_M1_ICESTORM_PRO, "Icestorm Pro" },
> ++ { CPU_PART_M1_FIRESTORM_PRO, "Firestorm Pro" },
> ++ { CPU_PART_M1_ICESTORM_MAX, "Icestorm Max" },
> ++ { CPU_PART_M1_FIRESTORM_MAX, "Firestorm Max" },
> ++ { CPU_PART_M2_BLIZZARD, "Blizzard" },
> ++ { CPU_PART_M2_AVALANCHE, "Avalanche" },
> ++ { CPU_PART_M2_BLIZZARD_PRO, "Blizzard Pro" },
> ++ { CPU_PART_M2_AVALANCHE_PRO, "Avalanche Pro" },
> ++ { CPU_PART_M2_BLIZZARD_MAX, "Blizzard Max" },
> ++ { CPU_PART_M2_AVALANCHE_MAX, "Avalanche Max" },
> ++ CPU_PART_NONE,
> ++};
> ++
> + /* Unknown */
> + static const struct cpu_parts cpu_parts_none[] = {
> + CPU_PART_NONE,
> + };
> +
> + /*
> +- * Implementers table.
> ++ * Implementers table. From FreeBSD, but using OpenBSD strings
> + */
> + const struct cpu_implementers cpu_implementers[] = {
> ++ { CPU_IMPL_AMPERE, "Ampere", cpu_parts_ampere },
> ++ { CPU_IMPL_APPLE, "Apple", cpu_parts_apple },
> ++ { CPU_IMPL_APM, "Applied Micro",cpu_parts_apm },
> + { CPU_IMPL_ARM, "ARM", cpu_parts_arm },
> + { CPU_IMPL_BROADCOM, "Broadcom", cpu_parts_none },
> + { CPU_IMPL_CAVIUM, "Cavium", cpu_parts_cavium },
> + { CPU_IMPL_DEC, "DEC", cpu_parts_none },
> +- { CPU_IMPL_INFINEON, "IFX", cpu_parts_none },
> + { CPU_IMPL_FREESCALE, "Freescale", cpu_parts_none },
> +- { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none },
> +- { CPU_IMPL_APM, "APM", cpu_parts_none },
> +- { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_none },
> +- { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none },
> ++ { CPU_IMPL_FUJITSU, "Fujitsu", cpu_parts_none },
> ++ { CPU_IMPL_HISILICON, "HiSilicon", cpu_parts_none },
> ++ { CPU_IMPL_INFINEON, "IFX", cpu_parts_none },
> + { CPU_IMPL_INTEL, "Intel", cpu_parts_none },
> ++ { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none },
> ++ { CPU_IMPL_MICROSOFT, "Microsoft", cpu_parts_microsoft },
> ++ { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none },
> ++ { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_qcom },
> + CPU_IMPLEMENTER_NONE,
> + };
> +
> +-#ifdef __OpenBSD__
> +-// READ_SPECIALREG is not available from userland on OpenBSD.
> +-// Hardcode these values to the "lowest common denominator"
> +-unsigned long VM_Version::os_get_processor_features() {
> +- _cpu = CPU_IMPL_ARM;
> +- _model = CPU_PART_CORTEX_A53;
> +- _variant = 0;
> +- _revision = 0;
> +- return HWCAP_ASIMD;
> +-}
> +-#else
> +-unsigned long VM_Version::os_get_processor_features() {
> +- struct cpu_desc cpu_desc[1];
> +- struct cpu_desc user_cpu_desc;
> +- unsigned long auxv = 0;
> +- uint64_t id_aa64isar0, id_aa64pfr0;
> +-
> +- uint32_t midr;
> +- uint32_t impl_id;
> +- uint32_t part_id;
> +- uint32_t cpu = 0;
> ++static void
> ++lookup_cpu(int &_cpu, int &_model, int &_variant, int &_revision) {
> ++ int mib[] = { CTL_HW, HW_MODEL };
> ++ char descr[BUFSIZ];
> ++ char *part_name, *rv_str;
> ++ size_t descr_len = sizeof(descr);
> ++ size_t impl_name_len;
> ++ const struct cpu_parts *cpu_partsp = nullptr;
> + size_t i;
> +- const struct cpu_parts *cpu_partsp = NULL;
> +
> +- midr = READ_SPECIALREG(midr_el1);
> ++ if (sysctl(mib, nitems(mib), &descr, &descr_len, NULL, 0) == -1)
> ++ return;
> +
> +- impl_id = CPU_IMPL(midr);
> + for (i = 0; i < nitems(cpu_implementers); i++) {
> +- if (impl_id == cpu_implementers[i].impl_id ||
> +- cpu_implementers[i].impl_id == 0) {
> +- cpu_desc[cpu].cpu_impl = impl_id;
> +- cpu_desc[cpu].cpu_impl_name = cpu_implementers[i].impl_name;
> ++ impl_name_len = strlen(cpu_implementers[i].impl_name);
> ++ if (cpu_implementers[i].impl_id == 0 ||
> ++ strncmp(descr, cpu_implementers[i].impl_name, impl_name_len) == 0) {
> ++ _cpu = cpu_implementers[i].impl_id;
> + cpu_partsp = cpu_implementers[i].cpu_parts;
> + break;
> + }
> + }
> +
> +- part_id = CPU_PART(midr);
> +- for (i = 0; &cpu_partsp[i] != NULL; i++) {
> +- if (part_id == cpu_partsp[i].part_id || cpu_partsp[i].part_id == 0) {
> +- cpu_desc[cpu].cpu_part_num = part_id;
> +- cpu_desc[cpu].cpu_part_name = cpu_partsp[i].part_name;
> +- break;
> +- }
> +- }
> ++ if (_cpu == 0)
> ++ return;
> +
> +- cpu_desc[cpu].cpu_revision = CPU_REV(midr);
> +- cpu_desc[cpu].cpu_variant = CPU_VAR(midr);
> ++ // +1 to skip space +1 more because descr_len includes NUL
> ++ if (impl_name_len + 2 > descr_len)
> ++ return;
> +
> +- _cpu = cpu_desc[cpu].cpu_impl;
> +- _variant = cpu_desc[cpu].cpu_variant;
> +- _model = cpu_desc[cpu].cpu_part_num;
> +- _revision = cpu_desc[cpu].cpu_revision;
> ++ part_name = &descr[impl_name_len+1];
> +
> +- id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1);
> +- id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1);
> ++ rv_str = strrchr(part_name, ' ');
> ++ if (rv_str == nullptr)
> ++ return;
> +
> +- if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_BASE) {
> +- auxv = auxv | HWCAP_AES;
> +- }
> ++ // null term part_name and skip over it
> ++ *(rv_str++) = '\0';
> +
> +- if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_PMULL) {
> +- auxv = auxv | HWCAP_PMULL;
> ++ for (i = 0; &cpu_partsp[i] != nullptr; i++) {
> ++ if (cpu_partsp[i].part_id == 0 ||
> ++ strcmp(part_name, cpu_partsp[i].part_name) == 0) {
> ++ _model = cpu_partsp[i].part_id;
> ++ break;
> ++ }
> + }
> +
> +- if (ID_AA64ISAR0_SHA1_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA1_BASE) {
> +- auxv = auxv | HWCAP_SHA1;
> +- }
> ++ sscanf(rv_str, "r%up%u", &_variant, &_revision);
> ++}
> ++#endif // __OpenBSD__
> +
> +- if (ID_AA64ISAR0_SHA2_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA2_BASE) {
> +- auxv = auxv | HWCAP_SHA2;
> +- }
> ++unsigned long VM_Version::os_get_processor_features() {
> ++ unsigned long auxv = 0;
> +
> +- if (ID_AA64ISAR0_CRC32_VAL(id_aa64isar0) == ID_AA64ISAR0_CRC32_BASE) {
> +- auxv = auxv | HWCAP_CRC32;
> +- }
> ++#if defined(__FreeBSD__) || defined(__OpenBSD__)
> ++ /*
> ++ * Step 1: setup _features using elf_aux_info(3). Keep in sync with Linux.
> ++ */
> ++ elf_aux_info(AT_HWCAP, &auxv, sizeof(auxv));
> +
> +- if (ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_IMPL || \
> +- ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_HP ) {
> +- auxv = auxv | HWCAP_ASIMD;
> ++ /*
> ++ * Step 2: setup _cpu, _model, _variant and _revision using READ_SPECIALREG on
> ++ * midr_el1 if allowed. On OpenBSD fallback to sysctl hw.model and lookup from
> ++ * tables.
> ++ */
> ++#ifdef __FreeBSD__
> ++ uint32_t midr = READ_SPECIALREG(midr_el1);
> ++ _cpu = CPU_IMPL(midr);
> ++ _model = CPU_PART(midr);
> ++ _variant = CPU_VAR(midr);
> ++ _revision = CPU_REV(midr);
> ++#else
> ++ /* On OpenBSD READ_SPECIALREG is only available if HWCAP_CPUID is set */
> ++ if (auxv & HWCAP_CPUID) {
> ++ uint32_t midr = READ_SPECIALREG(midr_el1);
> ++ _cpu = CPU_IMPL(midr);
> ++ _model = CPU_PART(midr);
> ++ _variant = CPU_VAR(midr);
> ++ _revision = CPU_REV(midr);
> ++ } else {
> ++ lookup_cpu(_cpu, _model, _variant, _revision);
> + }
> ++#endif // __FreeBSD__
> ++#endif // __FreeBSD__ || __OpenBSD__
> +
> + return auxv;
> + }
> +-#endif
> Index: 11/Makefile
> ===================================================================
> RCS file: /cvs/ports/devel/jdk/11/Makefile,v
> diff -u -p -u -r1.67 Makefile
> --- 11/Makefile 5 Dec 2025 22:00:14 -0000 1.67
> +++ 11/Makefile 16 Dec 2025 19:33:50 -0000
> @@ -12,7 +12,7 @@ PACKAGE_VER= ${BASE_VER}.${PATCH_VER}.${
> PKGNAME= jdk-${PACKAGE_VER}
> PKGSTEM= jdk-11
> EPOCH= 0
> -REVISION= 0
> +REVISION= 1
>
> DIST_SUBDIR= jdk
> DISTNAME= jdk-${VERSION_STR}
> Index: 11/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> ===================================================================
> RCS file: 11/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> diff -N 11/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ 11/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp 16 Dec 2025 19:33:50 -0000
> @@ -0,0 +1,533 @@
> +Get hardware capablilites using elf_aux_info(3).
> +Detect CPU, model, variant and revision using READ_SPECIALREG
> +when HWCAP_CPUID is set, otherwise parse sysctl hw.model to
> +get needed info.
> +
> +Index: src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp
> +--- src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp.orig
> ++++ src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp
> +@@ -90,93 +90,85 @@ bool VM_Version::is_cpu_emulated() {
> + #else // __APPLE__
> +
> + #include "vm_version_aarch64.hpp"
> +-
> + #include <machine/armreg.h>
> +-#if defined (__FreeBSD__)
> +-#include <machine/elf.h>
> ++#if defined (__FreeBSD__) || defined (__OpenBSD__)
> ++#include <sys/auxv.h>
> + #endif
> +
> +-#ifndef HWCAP_ASIMD
> +-#define HWCAP_ASIMD (1<<1)
> +-#endif
> ++#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
> ++#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
> ++#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
> ++#define CPU_REV(midr) (((midr) >> 0) & 0xf)
> +
> +-#ifndef HWCAP_AES
> +-#define HWCAP_AES (1<<3)
> +-#endif
> ++#ifdef __OpenBSD__
> ++// For older processors on OpenBSD READ_SPECIALREG is not supported.
> ++// These constants and tables allow for looking up the cpu and model.
> +
> +-#ifndef HWCAP_PMULL
> +-#define HWCAP_PMULL (1<<4)
> +-#endif
> ++#include <sys/types.h>
> ++#include <sys/sysctl.h>
> ++#include <string.h>
> ++#include <stdio.h>
> +
> +-#ifndef HWCAP_SHA1
> +-#define HWCAP_SHA1 (1<<5)
> +-#endif
> +-
> +-#ifndef HWCAP_SHA2
> +-#define HWCAP_SHA2 (1<<6)
> +-#endif
> +-
> +-#ifndef HWCAP_CRC32
> +-#define HWCAP_CRC32 (1<<7)
> +-#endif
> +-
> +-#ifndef HWCAP_ATOMICS
> +-#define HWCAP_ATOMICS (1<<8)
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_SHIFT
> +-#define ID_AA64PFR0_AdvSIMD_SHIFT 20
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD
> +-#define ID_AA64PFR0_AdvSIMD(x) ((x) & (UL(0xf) << ID_AA64PFR0_AdvSIMD_SHIFT))
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_IMPL
> +-#define ID_AA64PFR0_AdvSIMD_IMPL (UL(0x0) << ID_AA64PFR0_AdvSIMD_SHIFT)
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_HP
> +-#define ID_AA64PFR0_AdvSIMD_HP (UL(0x1) << ID_AA64PFR0_AdvSIMD_SHIFT)
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_AES_VAL
> +-#define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_SHA1_VAL
> +-#define ID_AA64ISAR0_SHA1_VAL ID_AA64ISAR0_SHA1
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_SHA2_VAL
> +-#define ID_AA64ISAR0_SHA2_VAL ID_AA64ISAR0_SHA2
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_CRC32_VAL
> +-#define ID_AA64ISAR0_CRC32_VAL ID_AA64ISAR0_CRC32
> +-#endif
> +-
> + #define CPU_IMPL_ARM 0x41
> + #define CPU_IMPL_BROADCOM 0x42
> + #define CPU_IMPL_CAVIUM 0x43
> + #define CPU_IMPL_DEC 0x44
> ++#define CPU_IMPL_FUJITSU 0x46
> ++#define CPU_IMPL_HISILICON 0x48
> + #define CPU_IMPL_INFINEON 0x49
> + #define CPU_IMPL_FREESCALE 0x4D
> + #define CPU_IMPL_NVIDIA 0x4E
> + #define CPU_IMPL_APM 0x50
> + #define CPU_IMPL_QUALCOMM 0x51
> + #define CPU_IMPL_MARVELL 0x56
> ++#define CPU_IMPL_APPLE 0x61
> + #define CPU_IMPL_INTEL 0x69
> ++#define CPU_IMPL_AMPERE 0xC0
> ++#define CPU_IMPL_MICROSOFT 0x6D
> +
> + /* ARM Part numbers */
> + #define CPU_PART_FOUNDATION 0xD00
> +-#define CPU_PART_CORTEX_A35 0xD04
> ++#define CPU_PART_CORTEX_A34 0xD02
> + #define CPU_PART_CORTEX_A53 0xD03
> ++#define CPU_PART_CORTEX_A35 0xD04
> + #define CPU_PART_CORTEX_A55 0xD05
> ++#define CPU_PART_CORTEX_A65 0xD06
> + #define CPU_PART_CORTEX_A57 0xD07
> + #define CPU_PART_CORTEX_A72 0xD08
> + #define CPU_PART_CORTEX_A73 0xD09
> + #define CPU_PART_CORTEX_A75 0xD0A
> ++#define CPU_PART_CORTEX_A76 0xD0B
> ++#define CPU_PART_NEOVERSE_N1 0xD0C
> ++#define CPU_PART_CORTEX_A77 0xD0D
> ++#define CPU_PART_CORTEX_A76AE 0xD0E
> ++#define CPU_PART_AEM_V8 0xD0F
> ++#define CPU_PART_NEOVERSE_V1 0xD40
> ++#define CPU_PART_CORTEX_A78 0xD41
> ++#define CPU_PART_CORTEX_A78AE 0xD42
> ++#define CPU_PART_CORTEX_A65AE 0xD43
> ++#define CPU_PART_CORTEX_X1 0xD44
> ++#define CPU_PART_CORTEX_A510 0xD46
> ++#define CPU_PART_CORTEX_A710 0xD47
> ++#define CPU_PART_CORTEX_X2 0xD48
> ++#define CPU_PART_NEOVERSE_N2 0xD49
> ++#define CPU_PART_NEOVERSE_E1 0xD4A
> ++#define CPU_PART_CORTEX_A78C 0xD4B
> ++#define CPU_PART_CORTEX_X1C 0xD4C
> ++#define CPU_PART_CORTEX_A715 0xD4D
> ++#define CPU_PART_CORTEX_X3 0xD4E
> ++#define CPU_PART_NEOVERSE_V2 0xD4F
> ++#define CPU_PART_CORTEX_A520 0xD80
> ++#define CPU_PART_CORTEX_A720 0xD81
> ++#define CPU_PART_CORTEX_X4 0xD82
> ++#define CPU_PART_NEOVERSE_V3AE 0xD83
> ++#define CPU_PART_NEOVERSE_V3 0xD84
> ++#define CPU_PART_CORTEX_X925 0xD85
> ++#define CPU_PART_CORTEX_A725 0xD87
> ++#define CPU_PART_C1_NANO 0xD8A
> ++#define CPU_PART_C1_PRO 0xD8B
> ++#define CPU_PART_C1_ULTRA 0xD8C
> ++#define CPU_PART_NEOVERSE_N3 0xD8E
> ++#define CPU_PART_C1_PREMIUM 0xD90
> +
> + /* Cavium Part numbers */
> + #define CPU_PART_THUNDERX 0x0A1
> +@@ -189,21 +181,35 @@ bool VM_Version::is_cpu_emulated() {
> +
> + #define CPU_REV_THUNDERX2_0 0x00
> +
> +-#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
> +-#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
> +-#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
> +-#define CPU_REV(midr) (((midr) >> 0) & 0xf)
> +-#define UL(x) UINT64_C(x)
> ++/* APM (now Ampere) Part number */
> ++#define CPU_PART_EMAG8180 0x000
> +
> +-struct cpu_desc {
> +- u_int cpu_impl;
> +- u_int cpu_part_num;
> +- u_int cpu_variant;
> +- u_int cpu_revision;
> +- const char *cpu_impl_name;
> +- const char *cpu_part_name;
> +-};
> ++/* Ampere Part numbers */
> ++#define CPU_PART_AMPERE1 0xAC3
> ++#define CPU_PART_AMPERE1A 0xAC4
> +
> ++/* Microsoft Part numbers */
> ++#define CPU_PART_AZURE_COBALT_100 0xD49
> ++
> ++/* Qualcomm */
> ++#define CPU_PART_ORYON 0x001
> ++#define CPU_PART_KRYO400_GOLD 0x804
> ++#define CPU_PART_KRYO400_SILVER 0x805
> ++
> ++/* Apple part numbers */
> ++#define CPU_PART_M1_ICESTORM 0x022
> ++#define CPU_PART_M1_FIRESTORM 0x023
> ++#define CPU_PART_M1_ICESTORM_PRO 0x024
> ++#define CPU_PART_M1_FIRESTORM_PRO 0x025
> ++#define CPU_PART_M1_ICESTORM_MAX 0x028
> ++#define CPU_PART_M1_FIRESTORM_MAX 0x029
> ++#define CPU_PART_M2_BLIZZARD 0x032
> ++#define CPU_PART_M2_AVALANCHE 0x033
> ++#define CPU_PART_M2_BLIZZARD_PRO 0x034
> ++#define CPU_PART_M2_AVALANCHE_PRO 0x035
> ++#define CPU_PART_M2_BLIZZARD_MAX 0x038
> ++#define CPU_PART_M2_AVALANCHE_MAX 0x039
> ++
> + struct cpu_parts {
> + u_int part_id;
> + const char *part_name;
> +@@ -224,136 +230,203 @@ struct cpu_implementers {
> + /*
> + * Per-implementer table of (PartNum, CPU Name) pairs.
> + */
> +-/* ARM Ltd. */
> ++/* ARM Ltd. From FreeBSD but using OpenBSD strings */
> + static const struct cpu_parts cpu_parts_arm[] = {
> ++ { CPU_PART_AEM_V8, "AEMv8" },
> + { CPU_PART_FOUNDATION, "Foundation-Model" },
> ++ { CPU_PART_CORTEX_A34, "Cortex-A34" },
> + { CPU_PART_CORTEX_A35, "Cortex-A35" },
> + { CPU_PART_CORTEX_A53, "Cortex-A53" },
> + { CPU_PART_CORTEX_A55, "Cortex-A55" },
> + { CPU_PART_CORTEX_A57, "Cortex-A57" },
> ++ { CPU_PART_CORTEX_A65, "Cortex-A65" },
> ++ { CPU_PART_CORTEX_A65AE, "Cortex-A65AE" },
> + { CPU_PART_CORTEX_A72, "Cortex-A72" },
> + { CPU_PART_CORTEX_A73, "Cortex-A73" },
> + { CPU_PART_CORTEX_A75, "Cortex-A75" },
> ++ { CPU_PART_CORTEX_A76, "Cortex-A76" },
> ++ { CPU_PART_CORTEX_A76AE, "Cortex-A76AE" },
> ++ { CPU_PART_CORTEX_A77, "Cortex-A77" },
> ++ { CPU_PART_CORTEX_A78, "Cortex-A78" },
> ++ { CPU_PART_CORTEX_A78AE, "Cortex-A78AE" },
> ++ { CPU_PART_CORTEX_A78C, "Cortex-A78C" },
> ++ { CPU_PART_CORTEX_A510, "Cortex-A510" },
> ++ { CPU_PART_CORTEX_A520, "Cortex-A520" },
> ++ { CPU_PART_CORTEX_A710, "Cortex-A710" },
> ++ { CPU_PART_CORTEX_A715, "Cortex-A715" },
> ++ { CPU_PART_CORTEX_A720, "Cortex-A720" },
> ++ { CPU_PART_CORTEX_A725, "Cortex-A725" },
> ++ { CPU_PART_CORTEX_X925, "Cortex-A925" },
> ++ { CPU_PART_CORTEX_X1C, "Cortex-X1C" },
> ++ { CPU_PART_CORTEX_X1, "Cortex-X1" },
> ++ { CPU_PART_CORTEX_X2, "Cortex-X2" },
> ++ { CPU_PART_CORTEX_X3, "Cortex-X3" },
> ++ { CPU_PART_CORTEX_X4, "Cortex-X4" },
> ++ { CPU_PART_C1_NANO, "C1-Nano" },
> ++ { CPU_PART_C1_PRO, "C1-Pro" },
> ++ { CPU_PART_C1_PREMIUM, "C1-Premium" },
> ++ { CPU_PART_C1_ULTRA, "C1-Ultra" },
> ++ { CPU_PART_NEOVERSE_E1, "Neoverse E1" },
> ++ { CPU_PART_NEOVERSE_N1, "Neoverse N1" },
> ++ { CPU_PART_NEOVERSE_N2, "Neoverse N2" },
> ++ { CPU_PART_NEOVERSE_N3, "Neoverse N3" },
> ++ { CPU_PART_NEOVERSE_V1, "Neoverse V1" },
> ++ { CPU_PART_NEOVERSE_V2, "Neoverse V2" },
> ++ { CPU_PART_NEOVERSE_V3, "Neoverse V3" },
> ++ { CPU_PART_NEOVERSE_V3AE, "Neoverse V3AE" },
> + CPU_PART_NONE,
> + };
> +-/* Cavium */
> ++
> ++/* Cavium From FreeBSD but using OpenBSD strings */
> + static const struct cpu_parts cpu_parts_cavium[] = {
> +- { CPU_PART_THUNDERX, "ThunderX" },
> +- { CPU_PART_THUNDERX2, "ThunderX2" },
> ++ { CPU_PART_THUNDERX, "ThunderX T88" },
> ++ { CPU_PART_THUNDERX_81XX, "ThunderX T81" },
> ++ { CPU_PART_THUNDERX_83XX, "ThunderX T83" },
> ++ { CPU_PART_THUNDERX2, "ThunderX2 T99" },
> + CPU_PART_NONE,
> + };
> +
> ++/* APM (now Ampere), From FreeBSD but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_apm[] = {
> ++ { CPU_PART_EMAG8180, "X-Gene" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Ampere From FreeBSD, but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_ampere[] = {
> ++ { CPU_PART_AMPERE1A, "AmpereOne AC04" },
> ++ { CPU_PART_AMPERE1, "AmpereOne" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Microsoft */
> ++static const struct cpu_parts cpu_parts_microsoft[] = {
> ++ { CPU_PART_AZURE_COBALT_100, "Azure Cobalt 100" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Qualcomm From FreeBSD & OpenBSD. */
> ++static const struct cpu_parts cpu_parts_qcom[] = {
> ++ { CPU_PART_KRYO400_GOLD, "Kryo 400 Gold" },
> ++ { CPU_PART_KRYO400_SILVER, "Kryo 400 Silver" },
> ++ { CPU_PART_ORYON, "Oryon" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Apple. From FreeBSD but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_apple[] = {
> ++ { CPU_PART_M1_ICESTORM, "Icestorm" },
> ++ { CPU_PART_M1_FIRESTORM, "Firestorm" },
> ++ { CPU_PART_M1_ICESTORM_PRO, "Icestorm Pro" },
> ++ { CPU_PART_M1_FIRESTORM_PRO, "Firestorm Pro" },
> ++ { CPU_PART_M1_ICESTORM_MAX, "Icestorm Max" },
> ++ { CPU_PART_M1_FIRESTORM_MAX, "Firestorm Max" },
> ++ { CPU_PART_M2_BLIZZARD, "Blizzard" },
> ++ { CPU_PART_M2_AVALANCHE, "Avalanche" },
> ++ { CPU_PART_M2_BLIZZARD_PRO, "Blizzard Pro" },
> ++ { CPU_PART_M2_AVALANCHE_PRO, "Avalanche Pro" },
> ++ { CPU_PART_M2_BLIZZARD_MAX, "Blizzard Max" },
> ++ { CPU_PART_M2_AVALANCHE_MAX, "Avalanche Max" },
> ++ CPU_PART_NONE,
> ++};
> ++
> + /* Unknown */
> + static const struct cpu_parts cpu_parts_none[] = {
> + CPU_PART_NONE,
> + };
> +
> + /*
> +- * Implementers table.
> ++ * Implementers table. From FreeBSD, but using OpenBSD strings
> + */
> + const struct cpu_implementers cpu_implementers[] = {
> ++ { CPU_IMPL_AMPERE, "Ampere", cpu_parts_ampere },
> ++ { CPU_IMPL_APPLE, "Apple", cpu_parts_apple },
> ++ { CPU_IMPL_APM, "Applied Micro",cpu_parts_apm },
> + { CPU_IMPL_ARM, "ARM", cpu_parts_arm },
> + { CPU_IMPL_BROADCOM, "Broadcom", cpu_parts_none },
> + { CPU_IMPL_CAVIUM, "Cavium", cpu_parts_cavium },
> + { CPU_IMPL_DEC, "DEC", cpu_parts_none },
> +- { CPU_IMPL_INFINEON, "IFX", cpu_parts_none },
> + { CPU_IMPL_FREESCALE, "Freescale", cpu_parts_none },
> +- { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none },
> +- { CPU_IMPL_APM, "APM", cpu_parts_none },
> +- { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_none },
> +- { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none },
> ++ { CPU_IMPL_FUJITSU, "Fujitsu", cpu_parts_none },
> ++ { CPU_IMPL_HISILICON, "HiSilicon", cpu_parts_none },
> ++ { CPU_IMPL_INFINEON, "IFX", cpu_parts_none },
> + { CPU_IMPL_INTEL, "Intel", cpu_parts_none },
> ++ { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none },
> ++ { CPU_IMPL_MICROSOFT, "Microsoft", cpu_parts_microsoft },
> ++ { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none },
> ++ { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_qcom },
> + CPU_IMPLEMENTER_NONE,
> + };
> +
> +-#ifdef __FreeBSD__
> +-static unsigned long os_get_processor_features() {
> +- unsigned long auxv = 0;
> +- uint64_t id_aa64isar0, id_aa64pfr0;
> ++static void
> ++lookup_cpu(int &_cpu, int &_model, int &_variant, int &_revision) {
> ++ int mib[] = { CTL_HW, HW_MODEL };
> ++ char descr[BUFSIZ];
> ++ char *part_name, *rv_str;
> ++ size_t descr_len = sizeof(descr);
> ++ size_t impl_name_len;
> ++ const struct cpu_parts *cpu_partsp = nullptr;
> ++ size_t i;
> +
> +- id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1);
> +- id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1);
> ++ if (sysctl(mib, nitems(mib), &descr, &descr_len, NULL, 0) == -1)
> ++ return;
> +
> +- if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_BASE) {
> +- auxv = auxv | HWCAP_AES;
> ++ for (i = 0; i < nitems(cpu_implementers); i++) {
> ++ impl_name_len = strlen(cpu_implementers[i].impl_name);
> ++ if (cpu_implementers[i].impl_id == 0 ||
> ++ strncmp(descr, cpu_implementers[i].impl_name, impl_name_len) == 0) {
> ++ _cpu = cpu_implementers[i].impl_id;
> ++ cpu_partsp = cpu_implementers[i].cpu_parts;
> ++ break;
> ++ }
> + }
> +
> +- if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_PMULL) {
> +- auxv = auxv | HWCAP_PMULL;
> +- }
> ++ if (_cpu == 0)
> ++ return;
> +
> +- if (ID_AA64ISAR0_SHA1_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA1_BASE) {
> +- auxv = auxv | HWCAP_SHA1;
> +- }
> ++ // +1 to skip space +1 more because descr_len includes NUL
> ++ if (impl_name_len + 2 > descr_len)
> ++ return;
> +
> +- if (ID_AA64ISAR0_SHA2_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA2_BASE) {
> +- auxv = auxv | HWCAP_SHA2;
> +- }
> ++ part_name = &descr[impl_name_len+1];
> +
> +- if (ID_AA64ISAR0_CRC32_VAL(id_aa64isar0) == ID_AA64ISAR0_CRC32_BASE) {
> +- auxv = auxv | HWCAP_CRC32;
> +- }
> ++ rv_str = strrchr(part_name, ' ');
> ++ if (rv_str == nullptr)
> ++ return;
> +
> +- if (ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_IMPL || \
> +- ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_HP ) {
> +- auxv = auxv | HWCAP_ASIMD;
> +- }
> ++ // null term part_name and skip over it
> ++ *(rv_str++) = '\0';
> +
> +- return auxv;
> +-}
> +-#endif
> +-
> +-void VM_Version::get_os_cpu_info() {
> +-#if defined(__OpenBSD__) || defined(__NetBSD__)
> +- // READ_SPECIALREG is not available from userland on OpenBSD.
> +- // Hardcode these values to the "lowest common denominator"
> +- _cpu = CPU_IMPL_ARM;
> +- _model = CPU_PART_CORTEX_A53;
> +- _variant = 0;
> +- _revision = 0;
> +- _features = HWCAP_ASIMD;
> +-#elif defined(__FreeBSD__)
> +- struct cpu_desc cpu_desc[1];
> +- struct cpu_desc user_cpu_desc;
> +-
> +- uint32_t midr;
> +- uint32_t impl_id;
> +- uint32_t part_id;
> +- uint32_t cpu = 0;
> +- size_t i;
> +- const struct cpu_parts *cpu_partsp = NULL;
> +-
> +- midr = READ_SPECIALREG(midr_el1);
> +-
> +- impl_id = CPU_IMPL(midr);
> +- for (i = 0; i < nitems(cpu_implementers); i++) {
> +- if (impl_id == cpu_implementers[i].impl_id ||
> +- cpu_implementers[i].impl_id == 0) {
> +- cpu_desc[cpu].cpu_impl = impl_id;
> +- cpu_desc[cpu].cpu_impl_name = cpu_implementers[i].impl_name;
> +- cpu_partsp = cpu_implementers[i].cpu_parts;
> ++ for (i = 0; &cpu_partsp[i] != nullptr; i++) {
> ++ if (cpu_partsp[i].part_id == 0 ||
> ++ strcmp(part_name, cpu_partsp[i].part_name) == 0) {
> ++ _model = cpu_partsp[i].part_id;
> + break;
> + }
> + }
> +- part_id = CPU_PART(midr);
> +- for (i = 0; &cpu_partsp[i] != NULL; i++) {
> +- if (part_id == cpu_partsp[i].part_id || cpu_partsp[i].part_id == 0) {
> +- cpu_desc[cpu].cpu_part_num = part_id;
> +- cpu_desc[cpu].cpu_part_name = cpu_partsp[i].part_name;
> +- break;
> +- }
> +- }
> +
> +- cpu_desc[cpu].cpu_revision = CPU_REV(midr);
> +- cpu_desc[cpu].cpu_variant = CPU_VAR(midr);
> ++ sscanf(rv_str, "r%up%u", &_variant, &_revision);
> ++}
> ++#endif // __OpenBSD__
> +
> +- _cpu = cpu_desc[cpu].cpu_impl;
> +- _variant = cpu_desc[cpu].cpu_variant;
> +- _model = cpu_desc[cpu].cpu_part_num;
> +- _revision = cpu_desc[cpu].cpu_revision;
> ++void VM_Version::get_os_cpu_info() {
> ++#if defined(__FreeBSD__) || defined(__OpenBSD__)
> +
> +- uint64_t auxv = os_get_processor_features();
> ++ /*
> ++ * Step 1: setup _features using elf_aux_info(3). Keep in sync with Linux.
> ++ */
> ++ unsigned long auxv = 0;
> ++ elf_aux_info(AT_HWCAP, &auxv, sizeof(auxv));
> +
> ++ STATIC_ASSERT(CPU_FP == HWCAP_FP);
> ++ STATIC_ASSERT(CPU_ASIMD == HWCAP_ASIMD);
> ++ STATIC_ASSERT(CPU_EVTSTRM == HWCAP_EVTSTRM);
> ++ STATIC_ASSERT(CPU_AES == HWCAP_AES);
> ++ STATIC_ASSERT(CPU_PMULL == HWCAP_PMULL);
> ++ STATIC_ASSERT(CPU_SHA1 == HWCAP_SHA1);
> ++ STATIC_ASSERT(CPU_SHA2 == HWCAP_SHA2);
> ++ STATIC_ASSERT(CPU_CRC32 == HWCAP_CRC32);
> ++ STATIC_ASSERT(CPU_LSE == HWCAP_ATOMICS);
> + _features = auxv & (
> + HWCAP_FP |
> + HWCAP_ASIMD |
> +@@ -363,13 +436,36 @@ void VM_Version::get_os_cpu_info() {
> + HWCAP_SHA1 |
> + HWCAP_SHA2 |
> + HWCAP_CRC32 |
> +- HWCAP_ATOMICS |
> +- HWCAP_DCPOP |
> +- HWCAP_SHA3 |
> +- HWCAP_SHA512 |
> +- HWCAP_SVE);
> +-#endif
> ++ HWCAP_ATOMICS);
> +
> ++ /*
> ++ * Step 2: setup _cpu, _model, _variant and _revision using READ_SPECIALREG on
> ++ * midr_el1 if allowed. On OpenBSD fallback to sysctl hw.model and lookup from
> ++ * tables.
> ++ */
> ++#ifdef __FreeBSD__
> ++ uint32_t midr = READ_SPECIALREG(midr_el1);
> ++ _cpu = CPU_IMPL(midr);
> ++ _model = CPU_PART(midr);
> ++ _variant = CPU_VAR(midr);
> ++ _revision = CPU_REV(midr);
> ++#else
> ++ /* On OpenBSD READ_SPECIALREG is only available if HWCAP_CPUID is set */
> ++ if (auxv & HWCAP_CPUID) {
> ++ uint32_t midr = READ_SPECIALREG(midr_el1);
> ++ _cpu = CPU_IMPL(midr);
> ++ _model = CPU_PART(midr);
> ++ _variant = CPU_VAR(midr);
> ++ _revision = CPU_REV(midr);
> ++ } else {
> ++ lookup_cpu(_cpu, _model, _variant, _revision);
> ++ }
> ++#endif // __FreeBSD__
> ++#endif // __FreeBSD__ || __OpenBSD__
> ++
> ++ /*
> ++ * Step 3: Get cache line sizes and _zva_length using same approach as Linux.
> ++ */
> + uint64_t ctr_el0;
> + uint64_t dczid_el0;
> + __asm__ (
> Index: 17/Makefile
> ===================================================================
> RCS file: /cvs/ports/devel/jdk/17/Makefile,v
> diff -u -p -u -r1.36 Makefile
> --- 17/Makefile 3 Nov 2025 13:44:13 -0000 1.36
> +++ 17/Makefile 16 Dec 2025 19:33:50 -0000
> @@ -12,6 +12,7 @@ PACKAGE_VER= ${BASE_VER}.${PATCH_VER}.${
> PKGNAME= jdk-${PACKAGE_VER}
> PKGSTEM= jdk-17
> EPOCH= 0
> +REVISION= 0
>
> DIST_SUBDIR= jdk
> DISTNAME= jdk-${VERSION_STR}
> Index: 17/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> ===================================================================
> RCS file: 17/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> diff -N 17/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ 17/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp 16 Dec 2025 19:33:50 -0000
> @@ -0,0 +1,533 @@
> +Get hardware capablilites using elf_aux_info(3).
> +Detect CPU, model, variant and revision using READ_SPECIALREG
> +when HWCAP_CPUID is set, otherwise parse sysctl hw.model to
> +get needed info.
> +
> +Index: src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp
> +--- src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp.orig
> ++++ src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp
> +@@ -104,91 +104,84 @@ bool VM_Version::is_cpu_emulated() {
> + #else // __APPLE__
> +
> + #include <machine/armreg.h>
> +-#if defined (__FreeBSD__)
> +-#include <machine/elf.h>
> ++#if defined (__FreeBSD__) || defined (__OpenBSD__)
> ++#include <sys/auxv.h>
> + #endif
> +
> +-#ifndef HWCAP_ASIMD
> +-#define HWCAP_ASIMD (1<<1)
> +-#endif
> ++#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
> ++#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
> ++#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
> ++#define CPU_REV(midr) (((midr) >> 0) & 0xf)
> +
> +-#ifndef HWCAP_AES
> +-#define HWCAP_AES (1<<3)
> +-#endif
> ++#ifdef __OpenBSD__
> ++// For older processors on OpenBSD READ_SPECIALREG is not supported.
> ++// These constants and tables allow for looking up the cpu and model.
> +
> +-#ifndef HWCAP_PMULL
> +-#define HWCAP_PMULL (1<<4)
> +-#endif
> ++#include <sys/types.h>
> ++#include <sys/sysctl.h>
> ++#include <string.h>
> ++#include <stdio.h>
> +
> +-#ifndef HWCAP_SHA1
> +-#define HWCAP_SHA1 (1<<5)
> +-#endif
> +-
> +-#ifndef HWCAP_SHA2
> +-#define HWCAP_SHA2 (1<<6)
> +-#endif
> +-
> +-#ifndef HWCAP_CRC32
> +-#define HWCAP_CRC32 (1<<7)
> +-#endif
> +-
> +-#ifndef HWCAP_ATOMICS
> +-#define HWCAP_ATOMICS (1<<8)
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_SHIFT
> +-#define ID_AA64PFR0_AdvSIMD_SHIFT 20
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD
> +-#define ID_AA64PFR0_AdvSIMD(x) ((x) & (UL(0xf) << ID_AA64PFR0_AdvSIMD_SHIFT))
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_IMPL
> +-#define ID_AA64PFR0_AdvSIMD_IMPL (UL(0x0) << ID_AA64PFR0_AdvSIMD_SHIFT)
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_HP
> +-#define ID_AA64PFR0_AdvSIMD_HP (UL(0x1) << ID_AA64PFR0_AdvSIMD_SHIFT)
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_AES_VAL
> +-#define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_SHA1_VAL
> +-#define ID_AA64ISAR0_SHA1_VAL ID_AA64ISAR0_SHA1
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_SHA2_VAL
> +-#define ID_AA64ISAR0_SHA2_VAL ID_AA64ISAR0_SHA2
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_CRC32_VAL
> +-#define ID_AA64ISAR0_CRC32_VAL ID_AA64ISAR0_CRC32
> +-#endif
> +-
> + #define CPU_IMPL_ARM 0x41
> + #define CPU_IMPL_BROADCOM 0x42
> + #define CPU_IMPL_CAVIUM 0x43
> + #define CPU_IMPL_DEC 0x44
> ++#define CPU_IMPL_FUJITSU 0x46
> ++#define CPU_IMPL_HISILICON 0x48
> + #define CPU_IMPL_INFINEON 0x49
> + #define CPU_IMPL_FREESCALE 0x4D
> + #define CPU_IMPL_NVIDIA 0x4E
> + #define CPU_IMPL_APM 0x50
> + #define CPU_IMPL_QUALCOMM 0x51
> + #define CPU_IMPL_MARVELL 0x56
> ++#define CPU_IMPL_APPLE 0x61
> + #define CPU_IMPL_INTEL 0x69
> ++#define CPU_IMPL_AMPERE 0xC0
> ++#define CPU_IMPL_MICROSOFT 0x6D
> +
> + /* ARM Part numbers */
> + #define CPU_PART_FOUNDATION 0xD00
> +-#define CPU_PART_CORTEX_A35 0xD04
> ++#define CPU_PART_CORTEX_A34 0xD02
> + #define CPU_PART_CORTEX_A53 0xD03
> ++#define CPU_PART_CORTEX_A35 0xD04
> + #define CPU_PART_CORTEX_A55 0xD05
> ++#define CPU_PART_CORTEX_A65 0xD06
> + #define CPU_PART_CORTEX_A57 0xD07
> + #define CPU_PART_CORTEX_A72 0xD08
> + #define CPU_PART_CORTEX_A73 0xD09
> + #define CPU_PART_CORTEX_A75 0xD0A
> ++#define CPU_PART_CORTEX_A76 0xD0B
> ++#define CPU_PART_NEOVERSE_N1 0xD0C
> ++#define CPU_PART_CORTEX_A77 0xD0D
> ++#define CPU_PART_CORTEX_A76AE 0xD0E
> ++#define CPU_PART_AEM_V8 0xD0F
> ++#define CPU_PART_NEOVERSE_V1 0xD40
> ++#define CPU_PART_CORTEX_A78 0xD41
> ++#define CPU_PART_CORTEX_A78AE 0xD42
> ++#define CPU_PART_CORTEX_A65AE 0xD43
> ++#define CPU_PART_CORTEX_X1 0xD44
> ++#define CPU_PART_CORTEX_A510 0xD46
> ++#define CPU_PART_CORTEX_A710 0xD47
> ++#define CPU_PART_CORTEX_X2 0xD48
> ++#define CPU_PART_NEOVERSE_N2 0xD49
> ++#define CPU_PART_NEOVERSE_E1 0xD4A
> ++#define CPU_PART_CORTEX_A78C 0xD4B
> ++#define CPU_PART_CORTEX_X1C 0xD4C
> ++#define CPU_PART_CORTEX_A715 0xD4D
> ++#define CPU_PART_CORTEX_X3 0xD4E
> ++#define CPU_PART_NEOVERSE_V2 0xD4F
> ++#define CPU_PART_CORTEX_A520 0xD80
> ++#define CPU_PART_CORTEX_A720 0xD81
> ++#define CPU_PART_CORTEX_X4 0xD82
> ++#define CPU_PART_NEOVERSE_V3AE 0xD83
> ++#define CPU_PART_NEOVERSE_V3 0xD84
> ++#define CPU_PART_CORTEX_X925 0xD85
> ++#define CPU_PART_CORTEX_A725 0xD87
> ++#define CPU_PART_C1_NANO 0xD8A
> ++#define CPU_PART_C1_PRO 0xD8B
> ++#define CPU_PART_C1_ULTRA 0xD8C
> ++#define CPU_PART_NEOVERSE_N3 0xD8E
> ++#define CPU_PART_C1_PREMIUM 0xD90
> +
> + /* Cavium Part numbers */
> + #define CPU_PART_THUNDERX 0x0A1
> +@@ -201,21 +194,35 @@ bool VM_Version::is_cpu_emulated() {
> +
> + #define CPU_REV_THUNDERX2_0 0x00
> +
> +-#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
> +-#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
> +-#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
> +-#define CPU_REV(midr) (((midr) >> 0) & 0xf)
> +-#define UL(x) UINT64_C(x)
> ++/* APM (now Ampere) Part number */
> ++#define CPU_PART_EMAG8180 0x000
> +
> +-struct cpu_desc {
> +- u_int cpu_impl;
> +- u_int cpu_part_num;
> +- u_int cpu_variant;
> +- u_int cpu_revision;
> +- const char *cpu_impl_name;
> +- const char *cpu_part_name;
> +-};
> ++/* Ampere Part numbers */
> ++#define CPU_PART_AMPERE1 0xAC3
> ++#define CPU_PART_AMPERE1A 0xAC4
> +
> ++/* Microsoft Part numbers */
> ++#define CPU_PART_AZURE_COBALT_100 0xD49
> ++
> ++/* Qualcomm */
> ++#define CPU_PART_ORYON 0x001
> ++#define CPU_PART_KRYO400_GOLD 0x804
> ++#define CPU_PART_KRYO400_SILVER 0x805
> ++
> ++/* Apple part numbers */
> ++#define CPU_PART_M1_ICESTORM 0x022
> ++#define CPU_PART_M1_FIRESTORM 0x023
> ++#define CPU_PART_M1_ICESTORM_PRO 0x024
> ++#define CPU_PART_M1_FIRESTORM_PRO 0x025
> ++#define CPU_PART_M1_ICESTORM_MAX 0x028
> ++#define CPU_PART_M1_FIRESTORM_MAX 0x029
> ++#define CPU_PART_M2_BLIZZARD 0x032
> ++#define CPU_PART_M2_AVALANCHE 0x033
> ++#define CPU_PART_M2_BLIZZARD_PRO 0x034
> ++#define CPU_PART_M2_AVALANCHE_PRO 0x035
> ++#define CPU_PART_M2_BLIZZARD_MAX 0x038
> ++#define CPU_PART_M2_AVALANCHE_MAX 0x039
> ++
> + struct cpu_parts {
> + u_int part_id;
> + const char *part_name;
> +@@ -236,136 +243,209 @@ struct cpu_implementers {
> + /*
> + * Per-implementer table of (PartNum, CPU Name) pairs.
> + */
> +-/* ARM Ltd. */
> ++/* ARM Ltd. From FreeBSD but using OpenBSD strings */
> + static const struct cpu_parts cpu_parts_arm[] = {
> ++ { CPU_PART_AEM_V8, "AEMv8" },
> + { CPU_PART_FOUNDATION, "Foundation-Model" },
> ++ { CPU_PART_CORTEX_A34, "Cortex-A34" },
> + { CPU_PART_CORTEX_A35, "Cortex-A35" },
> + { CPU_PART_CORTEX_A53, "Cortex-A53" },
> + { CPU_PART_CORTEX_A55, "Cortex-A55" },
> + { CPU_PART_CORTEX_A57, "Cortex-A57" },
> ++ { CPU_PART_CORTEX_A65, "Cortex-A65" },
> ++ { CPU_PART_CORTEX_A65AE, "Cortex-A65AE" },
> + { CPU_PART_CORTEX_A72, "Cortex-A72" },
> + { CPU_PART_CORTEX_A73, "Cortex-A73" },
> + { CPU_PART_CORTEX_A75, "Cortex-A75" },
> ++ { CPU_PART_CORTEX_A76, "Cortex-A76" },
> ++ { CPU_PART_CORTEX_A76AE, "Cortex-A76AE" },
> ++ { CPU_PART_CORTEX_A77, "Cortex-A77" },
> ++ { CPU_PART_CORTEX_A78, "Cortex-A78" },
> ++ { CPU_PART_CORTEX_A78AE, "Cortex-A78AE" },
> ++ { CPU_PART_CORTEX_A78C, "Cortex-A78C" },
> ++ { CPU_PART_CORTEX_A510, "Cortex-A510" },
> ++ { CPU_PART_CORTEX_A520, "Cortex-A520" },
> ++ { CPU_PART_CORTEX_A710, "Cortex-A710" },
> ++ { CPU_PART_CORTEX_A715, "Cortex-A715" },
> ++ { CPU_PART_CORTEX_A720, "Cortex-A720" },
> ++ { CPU_PART_CORTEX_A725, "Cortex-A725" },
> ++ { CPU_PART_CORTEX_X925, "Cortex-A925" },
> ++ { CPU_PART_CORTEX_X1C, "Cortex-X1C" },
> ++ { CPU_PART_CORTEX_X1, "Cortex-X1" },
> ++ { CPU_PART_CORTEX_X2, "Cortex-X2" },
> ++ { CPU_PART_CORTEX_X3, "Cortex-X3" },
> ++ { CPU_PART_CORTEX_X4, "Cortex-X4" },
> ++ { CPU_PART_C1_NANO, "C1-Nano" },
> ++ { CPU_PART_C1_PRO, "C1-Pro" },
> ++ { CPU_PART_C1_PREMIUM, "C1-Premium" },
> ++ { CPU_PART_C1_ULTRA, "C1-Ultra" },
> ++ { CPU_PART_NEOVERSE_E1, "Neoverse E1" },
> ++ { CPU_PART_NEOVERSE_N1, "Neoverse N1" },
> ++ { CPU_PART_NEOVERSE_N2, "Neoverse N2" },
> ++ { CPU_PART_NEOVERSE_N3, "Neoverse N3" },
> ++ { CPU_PART_NEOVERSE_V1, "Neoverse V1" },
> ++ { CPU_PART_NEOVERSE_V2, "Neoverse V2" },
> ++ { CPU_PART_NEOVERSE_V3, "Neoverse V3" },
> ++ { CPU_PART_NEOVERSE_V3AE, "Neoverse V3AE" },
> + CPU_PART_NONE,
> + };
> +-/* Cavium */
> ++
> ++/* Cavium From FreeBSD but using OpenBSD strings */
> + static const struct cpu_parts cpu_parts_cavium[] = {
> +- { CPU_PART_THUNDERX, "ThunderX" },
> +- { CPU_PART_THUNDERX2, "ThunderX2" },
> ++ { CPU_PART_THUNDERX, "ThunderX T88" },
> ++ { CPU_PART_THUNDERX_81XX, "ThunderX T81" },
> ++ { CPU_PART_THUNDERX_83XX, "ThunderX T83" },
> ++ { CPU_PART_THUNDERX2, "ThunderX2 T99" },
> + CPU_PART_NONE,
> + };
> +
> ++/* APM (now Ampere), From FreeBSD but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_apm[] = {
> ++ { CPU_PART_EMAG8180, "X-Gene" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Ampere From FreeBSD, but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_ampere[] = {
> ++ { CPU_PART_AMPERE1A, "AmpereOne AC04" },
> ++ { CPU_PART_AMPERE1, "AmpereOne" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Microsoft */
> ++static const struct cpu_parts cpu_parts_microsoft[] = {
> ++ { CPU_PART_AZURE_COBALT_100, "Azure Cobalt 100" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Qualcomm From FreeBSD & OpenBSD. */
> ++static const struct cpu_parts cpu_parts_qcom[] = {
> ++ { CPU_PART_KRYO400_GOLD, "Kryo 400 Gold" },
> ++ { CPU_PART_KRYO400_SILVER, "Kryo 400 Silver" },
> ++ { CPU_PART_ORYON, "Oryon" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Apple. From FreeBSD but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_apple[] = {
> ++ { CPU_PART_M1_ICESTORM, "Icestorm" },
> ++ { CPU_PART_M1_FIRESTORM, "Firestorm" },
> ++ { CPU_PART_M1_ICESTORM_PRO, "Icestorm Pro" },
> ++ { CPU_PART_M1_FIRESTORM_PRO, "Firestorm Pro" },
> ++ { CPU_PART_M1_ICESTORM_MAX, "Icestorm Max" },
> ++ { CPU_PART_M1_FIRESTORM_MAX, "Firestorm Max" },
> ++ { CPU_PART_M2_BLIZZARD, "Blizzard" },
> ++ { CPU_PART_M2_AVALANCHE, "Avalanche" },
> ++ { CPU_PART_M2_BLIZZARD_PRO, "Blizzard Pro" },
> ++ { CPU_PART_M2_AVALANCHE_PRO, "Avalanche Pro" },
> ++ { CPU_PART_M2_BLIZZARD_MAX, "Blizzard Max" },
> ++ { CPU_PART_M2_AVALANCHE_MAX, "Avalanche Max" },
> ++ CPU_PART_NONE,
> ++};
> ++
> + /* Unknown */
> + static const struct cpu_parts cpu_parts_none[] = {
> + CPU_PART_NONE,
> + };
> +
> + /*
> +- * Implementers table.
> ++ * Implementers table. From FreeBSD, but using OpenBSD strings
> + */
> + const struct cpu_implementers cpu_implementers[] = {
> ++ { CPU_IMPL_AMPERE, "Ampere", cpu_parts_ampere },
> ++ { CPU_IMPL_APPLE, "Apple", cpu_parts_apple },
> ++ { CPU_IMPL_APM, "Applied Micro",cpu_parts_apm },
> + { CPU_IMPL_ARM, "ARM", cpu_parts_arm },
> + { CPU_IMPL_BROADCOM, "Broadcom", cpu_parts_none },
> + { CPU_IMPL_CAVIUM, "Cavium", cpu_parts_cavium },
> + { CPU_IMPL_DEC, "DEC", cpu_parts_none },
> +- { CPU_IMPL_INFINEON, "IFX", cpu_parts_none },
> + { CPU_IMPL_FREESCALE, "Freescale", cpu_parts_none },
> +- { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none },
> +- { CPU_IMPL_APM, "APM", cpu_parts_none },
> +- { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_none },
> +- { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none },
> ++ { CPU_IMPL_FUJITSU, "Fujitsu", cpu_parts_none },
> ++ { CPU_IMPL_HISILICON, "HiSilicon", cpu_parts_none },
> ++ { CPU_IMPL_INFINEON, "IFX", cpu_parts_none },
> + { CPU_IMPL_INTEL, "Intel", cpu_parts_none },
> ++ { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none },
> ++ { CPU_IMPL_MICROSOFT, "Microsoft", cpu_parts_microsoft },
> ++ { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none },
> ++ { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_qcom },
> + CPU_IMPLEMENTER_NONE,
> + };
> +
> +-#ifdef __FreeBSD__
> +-static unsigned long os_get_processor_features() {
> +- unsigned long auxv = 0;
> +- uint64_t id_aa64isar0, id_aa64pfr0;
> ++static void
> ++lookup_cpu(int &_cpu, int &_model, int &_variant, int &_revision) {
> ++ int mib[] = { CTL_HW, HW_MODEL };
> ++ char descr[BUFSIZ];
> ++ char *part_name, *rv_str;
> ++ size_t descr_len = sizeof(descr);
> ++ size_t impl_name_len;
> ++ const struct cpu_parts *cpu_partsp = nullptr;
> ++ size_t i;
> +
> +- id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1);
> +- id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1);
> ++ if (sysctl(mib, nitems(mib), &descr, &descr_len, NULL, 0) == -1)
> ++ return;
> +
> +- if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_BASE) {
> +- auxv = auxv | HWCAP_AES;
> ++ for (i = 0; i < nitems(cpu_implementers); i++) {
> ++ impl_name_len = strlen(cpu_implementers[i].impl_name);
> ++ if (cpu_implementers[i].impl_id == 0 ||
> ++ strncmp(descr, cpu_implementers[i].impl_name, impl_name_len) == 0) {
> ++ _cpu = cpu_implementers[i].impl_id;
> ++ cpu_partsp = cpu_implementers[i].cpu_parts;
> ++ break;
> ++ }
> + }
> +
> +- if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_PMULL) {
> +- auxv = auxv | HWCAP_PMULL;
> +- }
> ++ if (_cpu == 0)
> ++ return;
> +
> +- if (ID_AA64ISAR0_SHA1_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA1_BASE) {
> +- auxv = auxv | HWCAP_SHA1;
> +- }
> ++ // +1 to skip space +1 more because descr_len includes NUL
> ++ if (impl_name_len + 2 > descr_len)
> ++ return;
> +
> +- if (ID_AA64ISAR0_SHA2_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA2_BASE) {
> +- auxv = auxv | HWCAP_SHA2;
> +- }
> ++ part_name = &descr[impl_name_len+1];
> +
> +- if (ID_AA64ISAR0_CRC32_VAL(id_aa64isar0) == ID_AA64ISAR0_CRC32_BASE) {
> +- auxv = auxv | HWCAP_CRC32;
> +- }
> ++ rv_str = strrchr(part_name, ' ');
> ++ if (rv_str == nullptr)
> ++ return;
> +
> +- if (ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_IMPL || \
> +- ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_HP ) {
> +- auxv = auxv | HWCAP_ASIMD;
> +- }
> ++ // null term part_name and skip over it
> ++ *(rv_str++) = '\0';
> +
> +- return auxv;
> +-}
> +-#endif
> +-
> +-void VM_Version::get_os_cpu_info() {
> +-#ifdef __OpenBSD__
> +- // READ_SPECIALREG is not available from userland on OpenBSD.
> +- // Hardcode these values to the "lowest common denominator"
> +- _cpu = CPU_IMPL_ARM;
> +- _model = CPU_PART_CORTEX_A53;
> +- _variant = 0;
> +- _revision = 0;
> +- _features = HWCAP_ASIMD;
> +-#elif defined(__FreeBSD__)
> +- struct cpu_desc cpu_desc[1];
> +- struct cpu_desc user_cpu_desc;
> +-
> +- uint32_t midr;
> +- uint32_t impl_id;
> +- uint32_t part_id;
> +- uint32_t cpu = 0;
> +- size_t i;
> +- const struct cpu_parts *cpu_partsp = NULL;
> +-
> +- midr = READ_SPECIALREG(midr_el1);
> +-
> +- impl_id = CPU_IMPL(midr);
> +- for (i = 0; i < nitems(cpu_implementers); i++) {
> +- if (impl_id == cpu_implementers[i].impl_id ||
> +- cpu_implementers[i].impl_id == 0) {
> +- cpu_desc[cpu].cpu_impl = impl_id;
> +- cpu_desc[cpu].cpu_impl_name = cpu_implementers[i].impl_name;
> +- cpu_partsp = cpu_implementers[i].cpu_parts;
> ++ for (i = 0; &cpu_partsp[i] != nullptr; i++) {
> ++ if (cpu_partsp[i].part_id == 0 ||
> ++ strcmp(part_name, cpu_partsp[i].part_name) == 0) {
> ++ _model = cpu_partsp[i].part_id;
> + break;
> + }
> + }
> +- part_id = CPU_PART(midr);
> +- for (i = 0; &cpu_partsp[i] != NULL; i++) {
> +- if (part_id == cpu_partsp[i].part_id || cpu_partsp[i].part_id == 0) {
> +- cpu_desc[cpu].cpu_part_num = part_id;
> +- cpu_desc[cpu].cpu_part_name = cpu_partsp[i].part_name;
> +- break;
> +- }
> +- }
> +
> +- cpu_desc[cpu].cpu_revision = CPU_REV(midr);
> +- cpu_desc[cpu].cpu_variant = CPU_VAR(midr);
> ++ sscanf(rv_str, "r%up%u", &_variant, &_revision);
> ++}
> ++#endif // __OpenBSD__
> +
> +- _cpu = cpu_desc[cpu].cpu_impl;
> +- _variant = cpu_desc[cpu].cpu_variant;
> +- _model = cpu_desc[cpu].cpu_part_num;
> +- _revision = cpu_desc[cpu].cpu_revision;
> ++void VM_Version::get_os_cpu_info() {
> ++#if defined(__FreeBSD__) || defined(__OpenBSD__)
> +
> +- uint64_t auxv = os_get_processor_features();
> ++ /*
> ++ * Step 1: setup _features using elf_aux_info(3). Keep in sync with Linux.
> ++ */
> ++ unsigned long auxv = 0;
> ++ unsigned long auxv2 = 0;
> ++ elf_aux_info(AT_HWCAP, &auxv, sizeof(auxv));
> ++ elf_aux_info(AT_HWCAP2, &auxv2, sizeof(auxv2));
> +
> ++ static_assert(CPU_FP == HWCAP_FP, "Flag CPU_FP must follow Linux HWCAP");
> ++ static_assert(CPU_ASIMD == HWCAP_ASIMD, "Flag CPU_ASIMD must follow Linux HWCAP");
> ++ static_assert(CPU_EVTSTRM == HWCAP_EVTSTRM, "Flag CPU_EVTSTRM must follow Linux HWCAP");
> ++ static_assert(CPU_AES == HWCAP_AES, "Flag CPU_AES must follow Linux HWCAP");
> ++ static_assert(CPU_PMULL == HWCAP_PMULL, "Flag CPU_PMULL must follow Linux HWCAP");
> ++ static_assert(CPU_SHA1 == HWCAP_SHA1, "Flag CPU_SHA1 must follow Linux HWCAP");
> ++ static_assert(CPU_SHA2 == HWCAP_SHA2, "Flag CPU_SHA2 must follow Linux HWCAP");
> ++ static_assert(CPU_CRC32 == HWCAP_CRC32, "Flag CPU_CRC32 must follow Linux HWCAP");
> ++ static_assert(CPU_LSE == HWCAP_ATOMICS, "Flag CPU_LSE must follow Linux HWCAP");
> ++ static_assert(CPU_DCPOP == HWCAP_DCPOP, "Flag CPU_DCPOP must follow Linux HWCAP");
> ++ static_assert(CPU_SHA3 == HWCAP_SHA3, "Flag CPU_SHA3 must follow Linux HWCAP");
> ++ static_assert(CPU_SHA512 == HWCAP_SHA512, "Flag CPU_SHA512 must follow Linux HWCAP");
> ++ static_assert(CPU_SVE == HWCAP_SVE, "Flag CPU_SVE must follow Linux HWCAP");
> + _features = auxv & (
> + HWCAP_FP |
> + HWCAP_ASIMD |
> +@@ -380,8 +460,37 @@ void VM_Version::get_os_cpu_info() {
> + HWCAP_SHA3 |
> + HWCAP_SHA512 |
> + HWCAP_SVE);
> +-#endif
> +
> ++ if (auxv2 & HWCAP2_SVE2) _features |= CPU_SVE2;
> ++
> ++ /*
> ++ * Step 2: setup _cpu, _model, _variant and _revision using READ_SPECIALREG on
> ++ * midr_el1 if allowed. On OpenBSD fallback to sysctl hw.model and lookup from
> ++ * tables.
> ++ */
> ++#ifdef __FreeBSD__
> ++ uint32_t midr = READ_SPECIALREG(midr_el1);
> ++ _cpu = CPU_IMPL(midr);
> ++ _model = CPU_PART(midr);
> ++ _variant = CPU_VAR(midr);
> ++ _revision = CPU_REV(midr);
> ++#else
> ++ /* On OpenBSD READ_SPECIALREG is only available if HWCAP_CPUID is set */
> ++ if (auxv & HWCAP_CPUID) {
> ++ uint32_t midr = READ_SPECIALREG(midr_el1);
> ++ _cpu = CPU_IMPL(midr);
> ++ _model = CPU_PART(midr);
> ++ _variant = CPU_VAR(midr);
> ++ _revision = CPU_REV(midr);
> ++ } else {
> ++ lookup_cpu(_cpu, _model, _variant, _revision);
> ++ }
> ++#endif // __FreeBSD__
> ++#endif // __FreeBSD__ || __OpenBSD__
> ++
> ++ /*
> ++ * Step 3: Get cache line sizes and _zva_length using same approach as Linux.
> ++ */
> + uint64_t ctr_el0;
> + uint64_t dczid_el0;
> + __asm__ (
> Index: 21/Makefile
> ===================================================================
> RCS file: /cvs/ports/devel/jdk/21/Makefile,v
> diff -u -p -u -r1.10 Makefile
> --- 21/Makefile 3 Nov 2025 15:43:43 -0000 1.10
> +++ 21/Makefile 16 Dec 2025 19:33:50 -0000
> @@ -12,6 +12,7 @@ PACKAGE_VER= ${BASE_VER}.${PATCH_VER}.${
> PKGNAME= jdk-${PACKAGE_VER}
> PKGSTEM= jdk-21
> EPOCH= 0
> +REVISION= 0
>
> DIST_SUBDIR= jdk
> DISTNAME= jdk-${VERSION_STR}
> Index: 21/patches/patch-make_common_NativeCompilation_gmk
> ===================================================================
> RCS file: /cvs/ports/devel/jdk/21/patches/patch-make_common_NativeCompilation_gmk,v
> diff -u -p -u -r1.1.1.1 patch-make_common_NativeCompilation_gmk
> --- 21/patches/patch-make_common_NativeCompilation_gmk 11 Dec 2023 14:36:21 -0000 1.1.1.1
> +++ 21/patches/patch-make_common_NativeCompilation_gmk 16 Dec 2025 19:33:50 -0000
> @@ -5,7 +5,7 @@ get the debug package without bloating t
> Index: make/common/NativeCompilation.gmk
> --- make/common/NativeCompilation.gmk.orig
> +++ make/common/NativeCompilation.gmk
> -@@ -1066,9 +1066,8 @@ define SetupNativeCompilationBody
> +@@ -1080,9 +1080,8 @@ define SetupNativeCompilationBody
> # so we can run it after strip is called, since strip can sometimes mangle the
> # embedded debuglink, which we want to avoid.
> $1_CREATE_DEBUGINFO_CMDS := \
> Index: 21/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> ===================================================================
> RCS file: 21/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> diff -N 21/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ 21/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp 16 Dec 2025 19:33:50 -0000
> @@ -0,0 +1,537 @@
> +Get hardware capablilites using elf_aux_info(3).
> +Detect CPU, model, variant and revision using READ_SPECIALREG
> +when HWCAP_CPUID is set, otherwise parse sysctl hw.model to
> +get needed info.
> +
> +Index: src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp
> +--- src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp.orig
> ++++ src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp
> +@@ -135,91 +135,84 @@ bool VM_Version::is_cpu_emulated() {
> + #else // __APPLE__
> +
> + #include <machine/armreg.h>
> +-#if defined (__FreeBSD__)
> +-#include <machine/elf.h>
> ++#if defined (__FreeBSD__) || defined (__OpenBSD__)
> ++#include <sys/auxv.h>
> + #endif
> +
> +-#ifndef HWCAP_ASIMD
> +-#define HWCAP_ASIMD (1<<1)
> +-#endif
> ++#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
> ++#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
> ++#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
> ++#define CPU_REV(midr) (((midr) >> 0) & 0xf)
> +
> +-#ifndef HWCAP_AES
> +-#define HWCAP_AES (1<<3)
> +-#endif
> ++#ifdef __OpenBSD__
> ++// For older processors on OpenBSD READ_SPECIALREG is not supported.
> ++// These constants and tables allow for looking up the cpu and model.
> +
> +-#ifndef HWCAP_PMULL
> +-#define HWCAP_PMULL (1<<4)
> +-#endif
> ++#include <sys/types.h>
> ++#include <sys/sysctl.h>
> ++#include <string.h>
> ++#include <stdio.h>
> +
> +-#ifndef HWCAP_SHA1
> +-#define HWCAP_SHA1 (1<<5)
> +-#endif
> +-
> +-#ifndef HWCAP_SHA2
> +-#define HWCAP_SHA2 (1<<6)
> +-#endif
> +-
> +-#ifndef HWCAP_CRC32
> +-#define HWCAP_CRC32 (1<<7)
> +-#endif
> +-
> +-#ifndef HWCAP_ATOMICS
> +-#define HWCAP_ATOMICS (1<<8)
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_SHIFT
> +-#define ID_AA64PFR0_AdvSIMD_SHIFT 20
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD
> +-#define ID_AA64PFR0_AdvSIMD(x) ((x) & (UL(0xf) << ID_AA64PFR0_AdvSIMD_SHIFT))
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_IMPL
> +-#define ID_AA64PFR0_AdvSIMD_IMPL (UL(0x0) << ID_AA64PFR0_AdvSIMD_SHIFT)
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_HP
> +-#define ID_AA64PFR0_AdvSIMD_HP (UL(0x1) << ID_AA64PFR0_AdvSIMD_SHIFT)
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_AES_VAL
> +-#define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_SHA1_VAL
> +-#define ID_AA64ISAR0_SHA1_VAL ID_AA64ISAR0_SHA1
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_SHA2_VAL
> +-#define ID_AA64ISAR0_SHA2_VAL ID_AA64ISAR0_SHA2
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_CRC32_VAL
> +-#define ID_AA64ISAR0_CRC32_VAL ID_AA64ISAR0_CRC32
> +-#endif
> +-
> + #define CPU_IMPL_ARM 0x41
> + #define CPU_IMPL_BROADCOM 0x42
> + #define CPU_IMPL_CAVIUM 0x43
> + #define CPU_IMPL_DEC 0x44
> ++#define CPU_IMPL_FUJITSU 0x46
> ++#define CPU_IMPL_HISILICON 0x48
> + #define CPU_IMPL_INFINEON 0x49
> + #define CPU_IMPL_FREESCALE 0x4D
> + #define CPU_IMPL_NVIDIA 0x4E
> + #define CPU_IMPL_APM 0x50
> + #define CPU_IMPL_QUALCOMM 0x51
> + #define CPU_IMPL_MARVELL 0x56
> ++#define CPU_IMPL_APPLE 0x61
> + #define CPU_IMPL_INTEL 0x69
> ++#define CPU_IMPL_AMPERE 0xC0
> ++#define CPU_IMPL_MICROSOFT 0x6D
> +
> + /* ARM Part numbers */
> + #define CPU_PART_FOUNDATION 0xD00
> +-#define CPU_PART_CORTEX_A35 0xD04
> ++#define CPU_PART_CORTEX_A34 0xD02
> + #define CPU_PART_CORTEX_A53 0xD03
> ++#define CPU_PART_CORTEX_A35 0xD04
> + #define CPU_PART_CORTEX_A55 0xD05
> ++#define CPU_PART_CORTEX_A65 0xD06
> + #define CPU_PART_CORTEX_A57 0xD07
> + #define CPU_PART_CORTEX_A72 0xD08
> + #define CPU_PART_CORTEX_A73 0xD09
> + #define CPU_PART_CORTEX_A75 0xD0A
> ++#define CPU_PART_CORTEX_A76 0xD0B
> ++#define CPU_PART_NEOVERSE_N1 0xD0C
> ++#define CPU_PART_CORTEX_A77 0xD0D
> ++#define CPU_PART_CORTEX_A76AE 0xD0E
> ++#define CPU_PART_AEM_V8 0xD0F
> ++#define CPU_PART_NEOVERSE_V1 0xD40
> ++#define CPU_PART_CORTEX_A78 0xD41
> ++#define CPU_PART_CORTEX_A78AE 0xD42
> ++#define CPU_PART_CORTEX_A65AE 0xD43
> ++#define CPU_PART_CORTEX_X1 0xD44
> ++#define CPU_PART_CORTEX_A510 0xD46
> ++#define CPU_PART_CORTEX_A710 0xD47
> ++#define CPU_PART_CORTEX_X2 0xD48
> ++#define CPU_PART_NEOVERSE_N2 0xD49
> ++#define CPU_PART_NEOVERSE_E1 0xD4A
> ++#define CPU_PART_CORTEX_A78C 0xD4B
> ++#define CPU_PART_CORTEX_X1C 0xD4C
> ++#define CPU_PART_CORTEX_A715 0xD4D
> ++#define CPU_PART_CORTEX_X3 0xD4E
> ++#define CPU_PART_NEOVERSE_V2 0xD4F
> ++#define CPU_PART_CORTEX_A520 0xD80
> ++#define CPU_PART_CORTEX_A720 0xD81
> ++#define CPU_PART_CORTEX_X4 0xD82
> ++#define CPU_PART_NEOVERSE_V3AE 0xD83
> ++#define CPU_PART_NEOVERSE_V3 0xD84
> ++#define CPU_PART_CORTEX_X925 0xD85
> ++#define CPU_PART_CORTEX_A725 0xD87
> ++#define CPU_PART_C1_NANO 0xD8A
> ++#define CPU_PART_C1_PRO 0xD8B
> ++#define CPU_PART_C1_ULTRA 0xD8C
> ++#define CPU_PART_NEOVERSE_N3 0xD8E
> ++#define CPU_PART_C1_PREMIUM 0xD90
> +
> + /* Cavium Part numbers */
> + #define CPU_PART_THUNDERX 0x0A1
> +@@ -232,21 +225,35 @@ bool VM_Version::is_cpu_emulated() {
> +
> + #define CPU_REV_THUNDERX2_0 0x00
> +
> +-#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
> +-#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
> +-#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
> +-#define CPU_REV(midr) (((midr) >> 0) & 0xf)
> +-#define UL(x) UINT64_C(x)
> ++/* APM (now Ampere) Part number */
> ++#define CPU_PART_EMAG8180 0x000
> +
> +-struct cpu_desc {
> +- u_int cpu_impl;
> +- u_int cpu_part_num;
> +- u_int cpu_variant;
> +- u_int cpu_revision;
> +- const char *cpu_impl_name;
> +- const char *cpu_part_name;
> +-};
> ++/* Ampere Part numbers */
> ++#define CPU_PART_AMPERE1 0xAC3
> ++#define CPU_PART_AMPERE1A 0xAC4
> +
> ++/* Microsoft Part numbers */
> ++#define CPU_PART_AZURE_COBALT_100 0xD49
> ++
> ++/* Qualcomm */
> ++#define CPU_PART_ORYON 0x001
> ++#define CPU_PART_KRYO400_GOLD 0x804
> ++#define CPU_PART_KRYO400_SILVER 0x805
> ++
> ++/* Apple part numbers */
> ++#define CPU_PART_M1_ICESTORM 0x022
> ++#define CPU_PART_M1_FIRESTORM 0x023
> ++#define CPU_PART_M1_ICESTORM_PRO 0x024
> ++#define CPU_PART_M1_FIRESTORM_PRO 0x025
> ++#define CPU_PART_M1_ICESTORM_MAX 0x028
> ++#define CPU_PART_M1_FIRESTORM_MAX 0x029
> ++#define CPU_PART_M2_BLIZZARD 0x032
> ++#define CPU_PART_M2_AVALANCHE 0x033
> ++#define CPU_PART_M2_BLIZZARD_PRO 0x034
> ++#define CPU_PART_M2_AVALANCHE_PRO 0x035
> ++#define CPU_PART_M2_BLIZZARD_MAX 0x038
> ++#define CPU_PART_M2_AVALANCHE_MAX 0x039
> ++
> + struct cpu_parts {
> + u_int part_id;
> + const char *part_name;
> +@@ -267,136 +274,210 @@ struct cpu_implementers {
> + /*
> + * Per-implementer table of (PartNum, CPU Name) pairs.
> + */
> +-/* ARM Ltd. */
> ++/* ARM Ltd. From FreeBSD but using OpenBSD strings */
> + static const struct cpu_parts cpu_parts_arm[] = {
> ++ { CPU_PART_AEM_V8, "AEMv8" },
> + { CPU_PART_FOUNDATION, "Foundation-Model" },
> ++ { CPU_PART_CORTEX_A34, "Cortex-A34" },
> + { CPU_PART_CORTEX_A35, "Cortex-A35" },
> + { CPU_PART_CORTEX_A53, "Cortex-A53" },
> + { CPU_PART_CORTEX_A55, "Cortex-A55" },
> + { CPU_PART_CORTEX_A57, "Cortex-A57" },
> ++ { CPU_PART_CORTEX_A65, "Cortex-A65" },
> ++ { CPU_PART_CORTEX_A65AE, "Cortex-A65AE" },
> + { CPU_PART_CORTEX_A72, "Cortex-A72" },
> + { CPU_PART_CORTEX_A73, "Cortex-A73" },
> + { CPU_PART_CORTEX_A75, "Cortex-A75" },
> ++ { CPU_PART_CORTEX_A76, "Cortex-A76" },
> ++ { CPU_PART_CORTEX_A76AE, "Cortex-A76AE" },
> ++ { CPU_PART_CORTEX_A77, "Cortex-A77" },
> ++ { CPU_PART_CORTEX_A78, "Cortex-A78" },
> ++ { CPU_PART_CORTEX_A78AE, "Cortex-A78AE" },
> ++ { CPU_PART_CORTEX_A78C, "Cortex-A78C" },
> ++ { CPU_PART_CORTEX_A510, "Cortex-A510" },
> ++ { CPU_PART_CORTEX_A520, "Cortex-A520" },
> ++ { CPU_PART_CORTEX_A710, "Cortex-A710" },
> ++ { CPU_PART_CORTEX_A715, "Cortex-A715" },
> ++ { CPU_PART_CORTEX_A720, "Cortex-A720" },
> ++ { CPU_PART_CORTEX_A725, "Cortex-A725" },
> ++ { CPU_PART_CORTEX_X925, "Cortex-A925" },
> ++ { CPU_PART_CORTEX_X1C, "Cortex-X1C" },
> ++ { CPU_PART_CORTEX_X1, "Cortex-X1" },
> ++ { CPU_PART_CORTEX_X2, "Cortex-X2" },
> ++ { CPU_PART_CORTEX_X3, "Cortex-X3" },
> ++ { CPU_PART_CORTEX_X4, "Cortex-X4" },
> ++ { CPU_PART_C1_NANO, "C1-Nano" },
> ++ { CPU_PART_C1_PRO, "C1-Pro" },
> ++ { CPU_PART_C1_PREMIUM, "C1-Premium" },
> ++ { CPU_PART_C1_ULTRA, "C1-Ultra" },
> ++ { CPU_PART_NEOVERSE_E1, "Neoverse E1" },
> ++ { CPU_PART_NEOVERSE_N1, "Neoverse N1" },
> ++ { CPU_PART_NEOVERSE_N2, "Neoverse N2" },
> ++ { CPU_PART_NEOVERSE_N3, "Neoverse N3" },
> ++ { CPU_PART_NEOVERSE_V1, "Neoverse V1" },
> ++ { CPU_PART_NEOVERSE_V2, "Neoverse V2" },
> ++ { CPU_PART_NEOVERSE_V3, "Neoverse V3" },
> ++ { CPU_PART_NEOVERSE_V3AE, "Neoverse V3AE" },
> + CPU_PART_NONE,
> + };
> +-/* Cavium */
> ++
> ++/* Cavium From FreeBSD but using OpenBSD strings */
> + static const struct cpu_parts cpu_parts_cavium[] = {
> +- { CPU_PART_THUNDERX, "ThunderX" },
> +- { CPU_PART_THUNDERX2, "ThunderX2" },
> ++ { CPU_PART_THUNDERX, "ThunderX T88" },
> ++ { CPU_PART_THUNDERX_81XX, "ThunderX T81" },
> ++ { CPU_PART_THUNDERX_83XX, "ThunderX T83" },
> ++ { CPU_PART_THUNDERX2, "ThunderX2 T99" },
> + CPU_PART_NONE,
> + };
> +
> ++/* APM (now Ampere), From FreeBSD but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_apm[] = {
> ++ { CPU_PART_EMAG8180, "X-Gene" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Ampere From FreeBSD, but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_ampere[] = {
> ++ { CPU_PART_AMPERE1A, "AmpereOne AC04" },
> ++ { CPU_PART_AMPERE1, "AmpereOne" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Microsoft */
> ++static const struct cpu_parts cpu_parts_microsoft[] = {
> ++ { CPU_PART_AZURE_COBALT_100, "Azure Cobalt 100" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Qualcomm From FreeBSD & OpenBSD. */
> ++static const struct cpu_parts cpu_parts_qcom[] = {
> ++ { CPU_PART_KRYO400_GOLD, "Kryo 400 Gold" },
> ++ { CPU_PART_KRYO400_SILVER, "Kryo 400 Silver" },
> ++ { CPU_PART_ORYON, "Oryon" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Apple. From FreeBSD but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_apple[] = {
> ++ { CPU_PART_M1_ICESTORM, "Icestorm" },
> ++ { CPU_PART_M1_FIRESTORM, "Firestorm" },
> ++ { CPU_PART_M1_ICESTORM_PRO, "Icestorm Pro" },
> ++ { CPU_PART_M1_FIRESTORM_PRO, "Firestorm Pro" },
> ++ { CPU_PART_M1_ICESTORM_MAX, "Icestorm Max" },
> ++ { CPU_PART_M1_FIRESTORM_MAX, "Firestorm Max" },
> ++ { CPU_PART_M2_BLIZZARD, "Blizzard" },
> ++ { CPU_PART_M2_AVALANCHE, "Avalanche" },
> ++ { CPU_PART_M2_BLIZZARD_PRO, "Blizzard Pro" },
> ++ { CPU_PART_M2_AVALANCHE_PRO, "Avalanche Pro" },
> ++ { CPU_PART_M2_BLIZZARD_MAX, "Blizzard Max" },
> ++ { CPU_PART_M2_AVALANCHE_MAX, "Avalanche Max" },
> ++ CPU_PART_NONE,
> ++};
> ++
> + /* Unknown */
> + static const struct cpu_parts cpu_parts_none[] = {
> + CPU_PART_NONE,
> + };
> +
> + /*
> +- * Implementers table.
> ++ * Implementers table. From FreeBSD, but using OpenBSD strings
> + */
> + const struct cpu_implementers cpu_implementers[] = {
> ++ { CPU_IMPL_AMPERE, "Ampere", cpu_parts_ampere },
> ++ { CPU_IMPL_APPLE, "Apple", cpu_parts_apple },
> ++ { CPU_IMPL_APM, "Applied Micro",cpu_parts_apm },
> + { CPU_IMPL_ARM, "ARM", cpu_parts_arm },
> + { CPU_IMPL_BROADCOM, "Broadcom", cpu_parts_none },
> + { CPU_IMPL_CAVIUM, "Cavium", cpu_parts_cavium },
> + { CPU_IMPL_DEC, "DEC", cpu_parts_none },
> +- { CPU_IMPL_INFINEON, "IFX", cpu_parts_none },
> + { CPU_IMPL_FREESCALE, "Freescale", cpu_parts_none },
> +- { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none },
> +- { CPU_IMPL_APM, "APM", cpu_parts_none },
> +- { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_none },
> +- { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none },
> ++ { CPU_IMPL_FUJITSU, "Fujitsu", cpu_parts_none },
> ++ { CPU_IMPL_HISILICON, "HiSilicon", cpu_parts_none },
> ++ { CPU_IMPL_INFINEON, "IFX", cpu_parts_none },
> + { CPU_IMPL_INTEL, "Intel", cpu_parts_none },
> ++ { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none },
> ++ { CPU_IMPL_MICROSOFT, "Microsoft", cpu_parts_microsoft },
> ++ { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none },
> ++ { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_qcom },
> + CPU_IMPLEMENTER_NONE,
> + };
> +
> +-#ifdef __FreeBSD__
> +-static unsigned long os_get_processor_features() {
> +- unsigned long auxv = 0;
> +- uint64_t id_aa64isar0, id_aa64pfr0;
> ++static void
> ++lookup_cpu(int &_cpu, int &_model, int &_variant, int &_revision) {
> ++ int mib[] = { CTL_HW, HW_MODEL };
> ++ char descr[BUFSIZ];
> ++ char *part_name, *rv_str;
> ++ size_t descr_len = sizeof(descr);
> ++ size_t impl_name_len;
> ++ const struct cpu_parts *cpu_partsp = nullptr;
> ++ size_t i;
> +
> +- id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1);
> +- id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1);
> ++ if (sysctl(mib, nitems(mib), &descr, &descr_len, NULL, 0) == -1)
> ++ return;
> +
> +- if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_BASE) {
> +- auxv = auxv | HWCAP_AES;
> ++ for (i = 0; i < nitems(cpu_implementers); i++) {
> ++ impl_name_len = strlen(cpu_implementers[i].impl_name);
> ++ if (cpu_implementers[i].impl_id == 0 ||
> ++ strncmp(descr, cpu_implementers[i].impl_name, impl_name_len) == 0) {
> ++ _cpu = cpu_implementers[i].impl_id;
> ++ cpu_partsp = cpu_implementers[i].cpu_parts;
> ++ break;
> ++ }
> + }
> +
> +- if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_PMULL) {
> +- auxv = auxv | HWCAP_PMULL;
> +- }
> ++ if (_cpu == 0)
> ++ return;
> +
> +- if (ID_AA64ISAR0_SHA1_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA1_BASE) {
> +- auxv = auxv | HWCAP_SHA1;
> +- }
> ++ // +1 to skip space +1 more because descr_len includes NUL
> ++ if (impl_name_len + 2 > descr_len)
> ++ return;
> +
> +- if (ID_AA64ISAR0_SHA2_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA2_BASE) {
> +- auxv = auxv | HWCAP_SHA2;
> +- }
> ++ part_name = &descr[impl_name_len+1];
> +
> +- if (ID_AA64ISAR0_CRC32_VAL(id_aa64isar0) == ID_AA64ISAR0_CRC32_BASE) {
> +- auxv = auxv | HWCAP_CRC32;
> +- }
> ++ rv_str = strrchr(part_name, ' ');
> ++ if (rv_str == nullptr)
> ++ return;
> +
> +- if (ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_IMPL || \
> +- ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_HP ) {
> +- auxv = auxv | HWCAP_ASIMD;
> +- }
> ++ // null term part_name and skip over it
> ++ *(rv_str++) = '\0';
> +
> +- return auxv;
> +-}
> +-#endif
> +-
> +-void VM_Version::get_os_cpu_info() {
> +-#ifdef __OpenBSD__
> +- // READ_SPECIALREG is not available from userland on OpenBSD.
> +- // Hardcode these values to the "lowest common denominator"
> +- _cpu = CPU_IMPL_ARM;
> +- _model = CPU_PART_CORTEX_A53;
> +- _variant = 0;
> +- _revision = 0;
> +- _features = HWCAP_ASIMD;
> +-#elif defined(__FreeBSD__)
> +- struct cpu_desc cpu_desc[1];
> +- struct cpu_desc user_cpu_desc;
> +-
> +- uint32_t midr;
> +- uint32_t impl_id;
> +- uint32_t part_id;
> +- uint32_t cpu = 0;
> +- size_t i;
> +- const struct cpu_parts *cpu_partsp = nullptr;
> +-
> +- midr = READ_SPECIALREG(midr_el1);
> +-
> +- impl_id = CPU_IMPL(midr);
> +- for (i = 0; i < nitems(cpu_implementers); i++) {
> +- if (impl_id == cpu_implementers[i].impl_id ||
> +- cpu_implementers[i].impl_id == 0) {
> +- cpu_desc[cpu].cpu_impl = impl_id;
> +- cpu_desc[cpu].cpu_impl_name = cpu_implementers[i].impl_name;
> +- cpu_partsp = cpu_implementers[i].cpu_parts;
> +- break;
> +- }
> +- }
> +- part_id = CPU_PART(midr);
> + for (i = 0; &cpu_partsp[i] != nullptr; i++) {
> +- if (part_id == cpu_partsp[i].part_id || cpu_partsp[i].part_id == 0) {
> +- cpu_desc[cpu].cpu_part_num = part_id;
> +- cpu_desc[cpu].cpu_part_name = cpu_partsp[i].part_name;
> ++ if (cpu_partsp[i].part_id == 0 ||
> ++ strcmp(part_name, cpu_partsp[i].part_name) == 0) {
> ++ _model = cpu_partsp[i].part_id;
> + break;
> + }
> + }
> +
> +- cpu_desc[cpu].cpu_revision = CPU_REV(midr);
> +- cpu_desc[cpu].cpu_variant = CPU_VAR(midr);
> ++ sscanf(rv_str, "r%up%u", &_variant, &_revision);
> ++}
> ++#endif // __OpenBSD__
> +
> +- _cpu = cpu_desc[cpu].cpu_impl;
> +- _variant = cpu_desc[cpu].cpu_variant;
> +- _model = cpu_desc[cpu].cpu_part_num;
> +- _revision = cpu_desc[cpu].cpu_revision;
> ++void VM_Version::get_os_cpu_info() {
> ++#if defined(__FreeBSD__) || defined(__OpenBSD__)
> +
> +- uint64_t auxv = os_get_processor_features();
> ++ /*
> ++ * Step 1: setup _features using elf_aux_info(3). Keep in sync with Linux.
> ++ */
> ++ unsigned long auxv = 0;
> ++ unsigned long auxv2 = 0;
> ++ elf_aux_info(AT_HWCAP, &auxv, sizeof(auxv));
> ++ elf_aux_info(AT_HWCAP2, &auxv2, sizeof(auxv2));
> +
> ++ static_assert(CPU_FP == HWCAP_FP, "Flag CPU_FP must follow HWCAP");
> ++ static_assert(CPU_ASIMD == HWCAP_ASIMD, "Flag CPU_ASIMD must follow HWCAP");
> ++ static_assert(CPU_EVTSTRM == HWCAP_EVTSTRM, "Flag CPU_EVTSTRM must follow HWCAP");
> ++ static_assert(CPU_AES == HWCAP_AES, "Flag CPU_AES must follow HWCAP");
> ++ static_assert(CPU_PMULL == HWCAP_PMULL, "Flag CPU_PMULL must follow HWCAP");
> ++ static_assert(CPU_SHA1 == HWCAP_SHA1, "Flag CPU_SHA1 must follow HWCAP");
> ++ static_assert(CPU_SHA2 == HWCAP_SHA2, "Flag CPU_SHA2 must follow HWCAP");
> ++ static_assert(CPU_CRC32 == HWCAP_CRC32, "Flag CPU_CRC32 must follow HWCAP");
> ++ static_assert(CPU_LSE == HWCAP_ATOMICS, "Flag CPU_LSE must follow HWCAP");
> ++ static_assert(CPU_DCPOP == HWCAP_DCPOP, "Flag CPU_DCPOP must follow HWCAP");
> ++ static_assert(CPU_SHA3 == HWCAP_SHA3, "Flag CPU_SHA3 must follow HWCAP");
> ++ static_assert(CPU_SHA512 == HWCAP_SHA512, "Flag CPU_SHA512 must follow HWCAP");
> ++ static_assert(CPU_SVE == HWCAP_SVE, "Flag CPU_SVE must follow HWCAP");
> ++ static_assert(CPU_PACA == HWCAP_PACA, "Flag CPU_PACA must follow HWCAP");
> + _features = auxv & (
> + HWCAP_FP |
> + HWCAP_ASIMD |
> +@@ -410,9 +491,40 @@ void VM_Version::get_os_cpu_info() {
> + HWCAP_DCPOP |
> + HWCAP_SHA3 |
> + HWCAP_SHA512 |
> +- HWCAP_SVE);
> +-#endif
> ++ HWCAP_SVE |
> ++ HWCAP_PACA);
> +
> ++ if (auxv2 & HWCAP2_SVE2) _features |= CPU_SVE2;
> ++ if (auxv2 & HWCAP2_SVEBITPERM) _features |= CPU_SVEBITPERM;
> ++
> ++ /*
> ++ * Step 2: setup _cpu, _model, _variant and _revision using READ_SPECIALREG on
> ++ * midr_el1 if allowed. On OpenBSD fallback to sysctl hw.model and lookup from
> ++ * tables.
> ++ */
> ++#ifdef __FreeBSD__
> ++ uint32_t midr = READ_SPECIALREG(midr_el1);
> ++ _cpu = CPU_IMPL(midr);
> ++ _model = CPU_PART(midr);
> ++ _variant = CPU_VAR(midr);
> ++ _revision = CPU_REV(midr);
> ++#else
> ++ /* On OpenBSD READ_SPECIALREG is only available if HWCAP_CPUID is set */
> ++ if (auxv & HWCAP_CPUID) {
> ++ uint32_t midr = READ_SPECIALREG(midr_el1);
> ++ _cpu = CPU_IMPL(midr);
> ++ _model = CPU_PART(midr);
> ++ _variant = CPU_VAR(midr);
> ++ _revision = CPU_REV(midr);
> ++ } else {
> ++ lookup_cpu(_cpu, _model, _variant, _revision);
> ++ }
> ++#endif // __FreeBSD__
> ++#endif // __FreeBSD__ || __OpenBSD__
> ++
> ++ /*
> ++ * Step 3: Get cache line sizes and _zva_length using same approach as Linux.
> ++ */
> + uint64_t ctr_el0;
> + uint64_t dczid_el0;
> + __asm__ (
> Index: 25/Makefile
> ===================================================================
> RCS file: /cvs/ports/devel/jdk/25/Makefile,v
> diff -u -p -u -r1.3 Makefile
> --- 25/Makefile 13 Nov 2025 22:48:44 -0000 1.3
> +++ 25/Makefile 16 Dec 2025 19:33:50 -0000
> @@ -12,6 +12,7 @@ PACKAGE_VER= ${BASE_VER}.${BUILD_VER}.${
> PKGNAME= jdk-${PACKAGE_VER}
> PKGSTEM= jdk-25
> EPOCH= 0
> +REVISION= 0
>
> DIST_SUBDIR= jdk
> DISTNAME= jdk-${VERSION_STR}
> Index: 25/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> ===================================================================
> RCS file: 25/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> diff -N 25/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ 25/patches/patch-src_hotspot_os_cpu_bsd_aarch64_vm_version_bsd_aarch64_cpp 16 Dec 2025 19:33:50 -0000
> @@ -0,0 +1,541 @@
> +Get hardware capablilites using elf_aux_info(3).
> +Detect CPU, model, variant and revision using READ_SPECIALREG
> +when HWCAP_CPUID is set, otherwise parse sysctl hw.model to
> +get needed info.
> +
> +Index: src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp
> +--- src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp.orig
> ++++ src/hotspot/os_cpu/bsd_aarch64/vm_version_bsd_aarch64.cpp
> +@@ -135,91 +135,84 @@ bool VM_Version::is_cpu_emulated() {
> + #else // __APPLE__
> +
> + #include <machine/armreg.h>
> +-#if defined (__FreeBSD__)
> +-#include <machine/elf.h>
> ++#if defined (__FreeBSD__) || defined (__OpenBSD__)
> ++#include <sys/auxv.h>
> + #endif
> +
> +-#ifndef HWCAP_ASIMD
> +-#define HWCAP_ASIMD (1<<1)
> +-#endif
> ++#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
> ++#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
> ++#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
> ++#define CPU_REV(midr) (((midr) >> 0) & 0xf)
> +
> +-#ifndef HWCAP_AES
> +-#define HWCAP_AES (1<<3)
> +-#endif
> ++#ifdef __OpenBSD__
> ++// For older processors on OpenBSD READ_SPECIALREG is not supported.
> ++// These constants and tables allow for looking up the cpu and model.
> +
> +-#ifndef HWCAP_PMULL
> +-#define HWCAP_PMULL (1<<4)
> +-#endif
> ++#include <sys/types.h>
> ++#include <sys/sysctl.h>
> ++#include <string.h>
> ++#include <stdio.h>
> +
> +-#ifndef HWCAP_SHA1
> +-#define HWCAP_SHA1 (1<<5)
> +-#endif
> +-
> +-#ifndef HWCAP_SHA2
> +-#define HWCAP_SHA2 (1<<6)
> +-#endif
> +-
> +-#ifndef HWCAP_CRC32
> +-#define HWCAP_CRC32 (1<<7)
> +-#endif
> +-
> +-#ifndef HWCAP_ATOMICS
> +-#define HWCAP_ATOMICS (1<<8)
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_SHIFT
> +-#define ID_AA64PFR0_AdvSIMD_SHIFT 20
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD
> +-#define ID_AA64PFR0_AdvSIMD(x) ((x) & (UL(0xf) << ID_AA64PFR0_AdvSIMD_SHIFT))
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_IMPL
> +-#define ID_AA64PFR0_AdvSIMD_IMPL (UL(0x0) << ID_AA64PFR0_AdvSIMD_SHIFT)
> +-#endif
> +-
> +-#ifndef ID_AA64PFR0_AdvSIMD_HP
> +-#define ID_AA64PFR0_AdvSIMD_HP (UL(0x1) << ID_AA64PFR0_AdvSIMD_SHIFT)
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_AES_VAL
> +-#define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_SHA1_VAL
> +-#define ID_AA64ISAR0_SHA1_VAL ID_AA64ISAR0_SHA1
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_SHA2_VAL
> +-#define ID_AA64ISAR0_SHA2_VAL ID_AA64ISAR0_SHA2
> +-#endif
> +-
> +-#ifndef ID_AA64ISAR0_CRC32_VAL
> +-#define ID_AA64ISAR0_CRC32_VAL ID_AA64ISAR0_CRC32
> +-#endif
> +-
> + #define CPU_IMPL_ARM 0x41
> + #define CPU_IMPL_BROADCOM 0x42
> + #define CPU_IMPL_CAVIUM 0x43
> + #define CPU_IMPL_DEC 0x44
> ++#define CPU_IMPL_FUJITSU 0x46
> ++#define CPU_IMPL_HISILICON 0x48
> + #define CPU_IMPL_INFINEON 0x49
> + #define CPU_IMPL_FREESCALE 0x4D
> + #define CPU_IMPL_NVIDIA 0x4E
> + #define CPU_IMPL_APM 0x50
> + #define CPU_IMPL_QUALCOMM 0x51
> + #define CPU_IMPL_MARVELL 0x56
> ++#define CPU_IMPL_APPLE 0x61
> + #define CPU_IMPL_INTEL 0x69
> ++#define CPU_IMPL_AMPERE 0xC0
> ++#define CPU_IMPL_MICROSOFT 0x6D
> +
> + /* ARM Part numbers */
> + #define CPU_PART_FOUNDATION 0xD00
> +-#define CPU_PART_CORTEX_A35 0xD04
> ++#define CPU_PART_CORTEX_A34 0xD02
> + #define CPU_PART_CORTEX_A53 0xD03
> ++#define CPU_PART_CORTEX_A35 0xD04
> + #define CPU_PART_CORTEX_A55 0xD05
> ++#define CPU_PART_CORTEX_A65 0xD06
> + #define CPU_PART_CORTEX_A57 0xD07
> + #define CPU_PART_CORTEX_A72 0xD08
> + #define CPU_PART_CORTEX_A73 0xD09
> + #define CPU_PART_CORTEX_A75 0xD0A
> ++#define CPU_PART_CORTEX_A76 0xD0B
> ++#define CPU_PART_NEOVERSE_N1 0xD0C
> ++#define CPU_PART_CORTEX_A77 0xD0D
> ++#define CPU_PART_CORTEX_A76AE 0xD0E
> ++#define CPU_PART_AEM_V8 0xD0F
> ++#define CPU_PART_NEOVERSE_V1 0xD40
> ++#define CPU_PART_CORTEX_A78 0xD41
> ++#define CPU_PART_CORTEX_A78AE 0xD42
> ++#define CPU_PART_CORTEX_A65AE 0xD43
> ++#define CPU_PART_CORTEX_X1 0xD44
> ++#define CPU_PART_CORTEX_A510 0xD46
> ++#define CPU_PART_CORTEX_A710 0xD47
> ++#define CPU_PART_CORTEX_X2 0xD48
> ++#define CPU_PART_NEOVERSE_N2 0xD49
> ++#define CPU_PART_NEOVERSE_E1 0xD4A
> ++#define CPU_PART_CORTEX_A78C 0xD4B
> ++#define CPU_PART_CORTEX_X1C 0xD4C
> ++#define CPU_PART_CORTEX_A715 0xD4D
> ++#define CPU_PART_CORTEX_X3 0xD4E
> ++#define CPU_PART_NEOVERSE_V2 0xD4F
> ++#define CPU_PART_CORTEX_A520 0xD80
> ++#define CPU_PART_CORTEX_A720 0xD81
> ++#define CPU_PART_CORTEX_X4 0xD82
> ++#define CPU_PART_NEOVERSE_V3AE 0xD83
> ++#define CPU_PART_NEOVERSE_V3 0xD84
> ++#define CPU_PART_CORTEX_X925 0xD85
> ++#define CPU_PART_CORTEX_A725 0xD87
> ++#define CPU_PART_C1_NANO 0xD8A
> ++#define CPU_PART_C1_PRO 0xD8B
> ++#define CPU_PART_C1_ULTRA 0xD8C
> ++#define CPU_PART_NEOVERSE_N3 0xD8E
> ++#define CPU_PART_C1_PREMIUM 0xD90
> +
> + /* Cavium Part numbers */
> + #define CPU_PART_THUNDERX 0x0A1
> +@@ -232,21 +225,35 @@ bool VM_Version::is_cpu_emulated() {
> +
> + #define CPU_REV_THUNDERX2_0 0x00
> +
> +-#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
> +-#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
> +-#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
> +-#define CPU_REV(midr) (((midr) >> 0) & 0xf)
> +-#define UL(x) UINT64_C(x)
> ++/* APM (now Ampere) Part number */
> ++#define CPU_PART_EMAG8180 0x000
> +
> +-struct cpu_desc {
> +- u_int cpu_impl;
> +- u_int cpu_part_num;
> +- u_int cpu_variant;
> +- u_int cpu_revision;
> +- const char *cpu_impl_name;
> +- const char *cpu_part_name;
> +-};
> ++/* Ampere Part numbers */
> ++#define CPU_PART_AMPERE1 0xAC3
> ++#define CPU_PART_AMPERE1A 0xAC4
> +
> ++/* Microsoft Part numbers */
> ++#define CPU_PART_AZURE_COBALT_100 0xD49
> ++
> ++/* Qualcomm */
> ++#define CPU_PART_ORYON 0x001
> ++#define CPU_PART_KRYO400_GOLD 0x804
> ++#define CPU_PART_KRYO400_SILVER 0x805
> ++
> ++/* Apple part numbers */
> ++#define CPU_PART_M1_ICESTORM 0x022
> ++#define CPU_PART_M1_FIRESTORM 0x023
> ++#define CPU_PART_M1_ICESTORM_PRO 0x024
> ++#define CPU_PART_M1_FIRESTORM_PRO 0x025
> ++#define CPU_PART_M1_ICESTORM_MAX 0x028
> ++#define CPU_PART_M1_FIRESTORM_MAX 0x029
> ++#define CPU_PART_M2_BLIZZARD 0x032
> ++#define CPU_PART_M2_AVALANCHE 0x033
> ++#define CPU_PART_M2_BLIZZARD_PRO 0x034
> ++#define CPU_PART_M2_AVALANCHE_PRO 0x035
> ++#define CPU_PART_M2_BLIZZARD_MAX 0x038
> ++#define CPU_PART_M2_AVALANCHE_MAX 0x039
> ++
> + struct cpu_parts {
> + u_int part_id;
> + const char *part_name;
> +@@ -267,136 +274,212 @@ struct cpu_implementers {
> + /*
> + * Per-implementer table of (PartNum, CPU Name) pairs.
> + */
> +-/* ARM Ltd. */
> ++/* ARM Ltd. From FreeBSD but using OpenBSD strings */
> + static const struct cpu_parts cpu_parts_arm[] = {
> ++ { CPU_PART_AEM_V8, "AEMv8" },
> + { CPU_PART_FOUNDATION, "Foundation-Model" },
> ++ { CPU_PART_CORTEX_A34, "Cortex-A34" },
> + { CPU_PART_CORTEX_A35, "Cortex-A35" },
> + { CPU_PART_CORTEX_A53, "Cortex-A53" },
> + { CPU_PART_CORTEX_A55, "Cortex-A55" },
> + { CPU_PART_CORTEX_A57, "Cortex-A57" },
> ++ { CPU_PART_CORTEX_A65, "Cortex-A65" },
> ++ { CPU_PART_CORTEX_A65AE, "Cortex-A65AE" },
> + { CPU_PART_CORTEX_A72, "Cortex-A72" },
> + { CPU_PART_CORTEX_A73, "Cortex-A73" },
> + { CPU_PART_CORTEX_A75, "Cortex-A75" },
> ++ { CPU_PART_CORTEX_A76, "Cortex-A76" },
> ++ { CPU_PART_CORTEX_A76AE, "Cortex-A76AE" },
> ++ { CPU_PART_CORTEX_A77, "Cortex-A77" },
> ++ { CPU_PART_CORTEX_A78, "Cortex-A78" },
> ++ { CPU_PART_CORTEX_A78AE, "Cortex-A78AE" },
> ++ { CPU_PART_CORTEX_A78C, "Cortex-A78C" },
> ++ { CPU_PART_CORTEX_A510, "Cortex-A510" },
> ++ { CPU_PART_CORTEX_A520, "Cortex-A520" },
> ++ { CPU_PART_CORTEX_A710, "Cortex-A710" },
> ++ { CPU_PART_CORTEX_A715, "Cortex-A715" },
> ++ { CPU_PART_CORTEX_A720, "Cortex-A720" },
> ++ { CPU_PART_CORTEX_A725, "Cortex-A725" },
> ++ { CPU_PART_CORTEX_X925, "Cortex-A925" },
> ++ { CPU_PART_CORTEX_X1C, "Cortex-X1C" },
> ++ { CPU_PART_CORTEX_X1, "Cortex-X1" },
> ++ { CPU_PART_CORTEX_X2, "Cortex-X2" },
> ++ { CPU_PART_CORTEX_X3, "Cortex-X3" },
> ++ { CPU_PART_CORTEX_X4, "Cortex-X4" },
> ++ { CPU_PART_C1_NANO, "C1-Nano" },
> ++ { CPU_PART_C1_PRO, "C1-Pro" },
> ++ { CPU_PART_C1_PREMIUM, "C1-Premium" },
> ++ { CPU_PART_C1_ULTRA, "C1-Ultra" },
> ++ { CPU_PART_NEOVERSE_E1, "Neoverse E1" },
> ++ { CPU_PART_NEOVERSE_N1, "Neoverse N1" },
> ++ { CPU_PART_NEOVERSE_N2, "Neoverse N2" },
> ++ { CPU_PART_NEOVERSE_N3, "Neoverse N3" },
> ++ { CPU_PART_NEOVERSE_V1, "Neoverse V1" },
> ++ { CPU_PART_NEOVERSE_V2, "Neoverse V2" },
> ++ { CPU_PART_NEOVERSE_V3, "Neoverse V3" },
> ++ { CPU_PART_NEOVERSE_V3AE, "Neoverse V3AE" },
> + CPU_PART_NONE,
> + };
> +-/* Cavium */
> ++
> ++/* Cavium From FreeBSD but using OpenBSD strings */
> + static const struct cpu_parts cpu_parts_cavium[] = {
> +- { CPU_PART_THUNDERX, "ThunderX" },
> +- { CPU_PART_THUNDERX2, "ThunderX2" },
> ++ { CPU_PART_THUNDERX, "ThunderX T88" },
> ++ { CPU_PART_THUNDERX_81XX, "ThunderX T81" },
> ++ { CPU_PART_THUNDERX_83XX, "ThunderX T83" },
> ++ { CPU_PART_THUNDERX2, "ThunderX2 T99" },
> + CPU_PART_NONE,
> + };
> +
> ++/* APM (now Ampere), From FreeBSD but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_apm[] = {
> ++ { CPU_PART_EMAG8180, "X-Gene" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Ampere From FreeBSD, but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_ampere[] = {
> ++ { CPU_PART_AMPERE1A, "AmpereOne AC04" },
> ++ { CPU_PART_AMPERE1, "AmpereOne" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Microsoft */
> ++static const struct cpu_parts cpu_parts_microsoft[] = {
> ++ { CPU_PART_AZURE_COBALT_100, "Azure Cobalt 100" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Qualcomm From FreeBSD & OpenBSD. */
> ++static const struct cpu_parts cpu_parts_qcom[] = {
> ++ { CPU_PART_KRYO400_GOLD, "Kryo 400 Gold" },
> ++ { CPU_PART_KRYO400_SILVER, "Kryo 400 Silver" },
> ++ { CPU_PART_ORYON, "Oryon" },
> ++ CPU_PART_NONE,
> ++};
> ++
> ++/* Apple. From FreeBSD but using OpenBSD strings */
> ++static const struct cpu_parts cpu_parts_apple[] = {
> ++ { CPU_PART_M1_ICESTORM, "Icestorm" },
> ++ { CPU_PART_M1_FIRESTORM, "Firestorm" },
> ++ { CPU_PART_M1_ICESTORM_PRO, "Icestorm Pro" },
> ++ { CPU_PART_M1_FIRESTORM_PRO, "Firestorm Pro" },
> ++ { CPU_PART_M1_ICESTORM_MAX, "Icestorm Max" },
> ++ { CPU_PART_M1_FIRESTORM_MAX, "Firestorm Max" },
> ++ { CPU_PART_M2_BLIZZARD, "Blizzard" },
> ++ { CPU_PART_M2_AVALANCHE, "Avalanche" },
> ++ { CPU_PART_M2_BLIZZARD_PRO, "Blizzard Pro" },
> ++ { CPU_PART_M2_AVALANCHE_PRO, "Avalanche Pro" },
> ++ { CPU_PART_M2_BLIZZARD_MAX, "Blizzard Max" },
> ++ { CPU_PART_M2_AVALANCHE_MAX, "Avalanche Max" },
> ++ CPU_PART_NONE,
> ++};
> ++
> + /* Unknown */
> + static const struct cpu_parts cpu_parts_none[] = {
> + CPU_PART_NONE,
> + };
> +
> + /*
> +- * Implementers table.
> ++ * Implementers table. From FreeBSD, but using OpenBSD strings
> + */
> + const struct cpu_implementers cpu_implementers[] = {
> ++ { CPU_IMPL_AMPERE, "Ampere", cpu_parts_ampere },
> ++ { CPU_IMPL_APPLE, "Apple", cpu_parts_apple },
> ++ { CPU_IMPL_APM, "Applied Micro",cpu_parts_apm },
> + { CPU_IMPL_ARM, "ARM", cpu_parts_arm },
> + { CPU_IMPL_BROADCOM, "Broadcom", cpu_parts_none },
> + { CPU_IMPL_CAVIUM, "Cavium", cpu_parts_cavium },
> + { CPU_IMPL_DEC, "DEC", cpu_parts_none },
> +- { CPU_IMPL_INFINEON, "IFX", cpu_parts_none },
> + { CPU_IMPL_FREESCALE, "Freescale", cpu_parts_none },
> +- { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none },
> +- { CPU_IMPL_APM, "APM", cpu_parts_none },
> +- { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_none },
> +- { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none },
> ++ { CPU_IMPL_FUJITSU, "Fujitsu", cpu_parts_none },
> ++ { CPU_IMPL_HISILICON, "HiSilicon", cpu_parts_none },
> ++ { CPU_IMPL_INFINEON, "IFX", cpu_parts_none },
> + { CPU_IMPL_INTEL, "Intel", cpu_parts_none },
> ++ { CPU_IMPL_MARVELL, "Marvell", cpu_parts_none },
> ++ { CPU_IMPL_MICROSOFT, "Microsoft", cpu_parts_microsoft },
> ++ { CPU_IMPL_NVIDIA, "NVIDIA", cpu_parts_none },
> ++ { CPU_IMPL_QUALCOMM, "Qualcomm", cpu_parts_qcom },
> + CPU_IMPLEMENTER_NONE,
> + };
> +
> +-#ifdef __FreeBSD__
> +-static unsigned long os_get_processor_features() {
> +- unsigned long auxv = 0;
> +- uint64_t id_aa64isar0, id_aa64pfr0;
> ++static void
> ++lookup_cpu(int &_cpu, int &_model, int &_variant, int &_revision) {
> ++ int mib[] = { CTL_HW, HW_MODEL };
> ++ char descr[BUFSIZ];
> ++ char *part_name, *rv_str;
> ++ size_t descr_len = sizeof(descr);
> ++ size_t impl_name_len;
> ++ const struct cpu_parts *cpu_partsp = nullptr;
> ++ size_t i;
> +
> +- id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1);
> +- id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1);
> ++ if (sysctl(mib, nitems(mib), &descr, &descr_len, NULL, 0) == -1)
> ++ return;
> +
> +- if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_BASE) {
> +- auxv = auxv | HWCAP_AES;
> ++ for (i = 0; i < nitems(cpu_implementers); i++) {
> ++ impl_name_len = strlen(cpu_implementers[i].impl_name);
> ++ if (cpu_implementers[i].impl_id == 0 ||
> ++ strncmp(descr, cpu_implementers[i].impl_name, impl_name_len) == 0) {
> ++ _cpu = cpu_implementers[i].impl_id;
> ++ cpu_partsp = cpu_implementers[i].cpu_parts;
> ++ break;
> ++ }
> + }
> +
> +- if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_PMULL) {
> +- auxv = auxv | HWCAP_PMULL;
> +- }
> ++ if (_cpu == 0)
> ++ return;
> +
> +- if (ID_AA64ISAR0_SHA1_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA1_BASE) {
> +- auxv = auxv | HWCAP_SHA1;
> +- }
> ++ // +1 to skip space +1 more because descr_len includes NUL
> ++ if (impl_name_len + 2 > descr_len)
> ++ return;
> +
> +- if (ID_AA64ISAR0_SHA2_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA2_BASE) {
> +- auxv = auxv | HWCAP_SHA2;
> +- }
> ++ part_name = &descr[impl_name_len+1];
> +
> +- if (ID_AA64ISAR0_CRC32_VAL(id_aa64isar0) == ID_AA64ISAR0_CRC32_BASE) {
> +- auxv = auxv | HWCAP_CRC32;
> +- }
> ++ rv_str = strrchr(part_name, ' ');
> ++ if (rv_str == nullptr)
> ++ return;
> +
> +- if (ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_IMPL || \
> +- ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_HP ) {
> +- auxv = auxv | HWCAP_ASIMD;
> +- }
> ++ // null term part_name and skip over it
> ++ *(rv_str++) = '\0';
> +
> +- return auxv;
> +-}
> +-#endif
> +-
> +-void VM_Version::get_os_cpu_info() {
> +-#ifdef __OpenBSD__
> +- // READ_SPECIALREG is not available from userland on OpenBSD.
> +- // Hardcode these values to the "lowest common denominator"
> +- _cpu = CPU_IMPL_ARM;
> +- _model = CPU_PART_CORTEX_A53;
> +- _variant = 0;
> +- _revision = 0;
> +- _features = HWCAP_ASIMD;
> +-#elif defined(__FreeBSD__)
> +- struct cpu_desc cpu_desc[1];
> +- struct cpu_desc user_cpu_desc;
> +-
> +- uint32_t midr;
> +- uint32_t impl_id;
> +- uint32_t part_id;
> +- uint32_t cpu = 0;
> +- size_t i;
> +- const struct cpu_parts *cpu_partsp = nullptr;
> +-
> +- midr = READ_SPECIALREG(midr_el1);
> +-
> +- impl_id = CPU_IMPL(midr);
> +- for (i = 0; i < nitems(cpu_implementers); i++) {
> +- if (impl_id == cpu_implementers[i].impl_id ||
> +- cpu_implementers[i].impl_id == 0) {
> +- cpu_desc[cpu].cpu_impl = impl_id;
> +- cpu_desc[cpu].cpu_impl_name = cpu_implementers[i].impl_name;
> +- cpu_partsp = cpu_implementers[i].cpu_parts;
> +- break;
> +- }
> +- }
> +- part_id = CPU_PART(midr);
> + for (i = 0; &cpu_partsp[i] != nullptr; i++) {
> +- if (part_id == cpu_partsp[i].part_id || cpu_partsp[i].part_id == 0) {
> +- cpu_desc[cpu].cpu_part_num = part_id;
> +- cpu_desc[cpu].cpu_part_name = cpu_partsp[i].part_name;
> ++ if (cpu_partsp[i].part_id == 0 ||
> ++ strcmp(part_name, cpu_partsp[i].part_name) == 0) {
> ++ _model = cpu_partsp[i].part_id;
> + break;
> + }
> + }
> +
> +- cpu_desc[cpu].cpu_revision = CPU_REV(midr);
> +- cpu_desc[cpu].cpu_variant = CPU_VAR(midr);
> ++ sscanf(rv_str, "r%up%u", &_variant, &_revision);
> ++}
> ++#endif // __OpenBSD__
> +
> +- _cpu = cpu_desc[cpu].cpu_impl;
> +- _variant = cpu_desc[cpu].cpu_variant;
> +- _model = cpu_desc[cpu].cpu_part_num;
> +- _revision = cpu_desc[cpu].cpu_revision;
> ++void VM_Version::get_os_cpu_info() {
> ++#if defined(__FreeBSD__) || defined(__OpenBSD__)
> +
> +- uint64_t auxv = os_get_processor_features();
> ++ /*
> ++ * Step 1: setup _features using elf_aux_info(3). Keep in sync with Linux.
> ++ */
> ++ unsigned long auxv = 0;
> ++ unsigned long auxv2 = 0;
> ++ elf_aux_info(AT_HWCAP, &auxv, sizeof(auxv));
> ++ elf_aux_info(AT_HWCAP2, &auxv2, sizeof(auxv2));
> +
> ++ static_assert(CPU_FP == HWCAP_FP, "Flag CPU_FP must follow HWCAP");
> ++ static_assert(CPU_ASIMD == HWCAP_ASIMD, "Flag CPU_ASIMD must follow HWCAP");
> ++ static_assert(CPU_EVTSTRM == HWCAP_EVTSTRM, "Flag CPU_EVTSTRM must follow HWCAP");
> ++ static_assert(CPU_AES == HWCAP_AES, "Flag CPU_AES must follow HWCAP");
> ++ static_assert(CPU_PMULL == HWCAP_PMULL, "Flag CPU_PMULL must follow HWCAP");
> ++ static_assert(CPU_SHA1 == HWCAP_SHA1, "Flag CPU_SHA1 must follow HWCAP");
> ++ static_assert(CPU_SHA2 == HWCAP_SHA2, "Flag CPU_SHA2 must follow HWCAP");
> ++ static_assert(CPU_CRC32 == HWCAP_CRC32, "Flag CPU_CRC32 must follow HWCAP");
> ++ static_assert(CPU_LSE == HWCAP_ATOMICS, "Flag CPU_LSE must follow HWCAP");
> ++ static_assert(CPU_DCPOP == HWCAP_DCPOP, "Flag CPU_DCPOP must follow HWCAP");
> ++ static_assert(CPU_SHA3 == HWCAP_SHA3, "Flag CPU_SHA3 must follow HWCAP");
> ++ static_assert(CPU_SHA512 == HWCAP_SHA512, "Flag CPU_SHA512 must follow HWCAP");
> ++ static_assert(CPU_SVE == HWCAP_SVE, "Flag CPU_SVE must follow HWCAP");
> ++ static_assert(CPU_PACA == HWCAP_PACA, "Flag CPU_PACA must follow HWCAP");
> ++ static_assert(CPU_FPHP == HWCAP_FPHP, "Flag CPU_FPHP must follow HWCAP");
> ++ static_assert(CPU_ASIMDHP == HWCAP_ASIMDHP, "Flag CPU_ASIMDHP must follow HWCAP");
> + _features = auxv & (
> + HWCAP_FP |
> + HWCAP_ASIMD |
> +@@ -410,9 +493,42 @@ void VM_Version::get_os_cpu_info() {
> + HWCAP_DCPOP |
> + HWCAP_SHA3 |
> + HWCAP_SHA512 |
> +- HWCAP_SVE);
> +-#endif
> ++ HWCAP_SVE |
> ++ HWCAP_PACA |
> ++ HWCAP_FPHP |
> ++ HWCAP_ASIMDHP);
> +
> ++ if (auxv2 & HWCAP2_SVE2) _features |= CPU_SVE2;
> ++ if (auxv2 & HWCAP2_SVEBITPERM) _features |= CPU_SVEBITPERM;
> ++
> ++ /*
> ++ * Step 2: setup _cpu, _model, _variant and _revision using READ_SPECIALREG on
> ++ * midr_el1 if allowed. On OpenBSD fallback to sysctl hw.model and lookup from
> ++ * tables.
> ++ */
> ++#ifdef __FreeBSD__
> ++ uint32_t midr = READ_SPECIALREG(midr_el1);
> ++ _cpu = CPU_IMPL(midr);
> ++ _model = CPU_PART(midr);
> ++ _variant = CPU_VAR(midr);
> ++ _revision = CPU_REV(midr);
> ++#else
> ++ /* On OpenBSD READ_SPECIALREG is only available if HWCAP_CPUID is set */
> ++ if (auxv & HWCAP_CPUID) {
> ++ uint32_t midr = READ_SPECIALREG(midr_el1);
> ++ _cpu = CPU_IMPL(midr);
> ++ _model = CPU_PART(midr);
> ++ _variant = CPU_VAR(midr);
> ++ _revision = CPU_REV(midr);
> ++ } else {
> ++ lookup_cpu(_cpu, _model, _variant, _revision);
> ++ }
> ++#endif // __FreeBSD__
> ++#endif // __FreeBSD__ || __OpenBSD__
> ++
> ++ /*
> ++ * Step 3: Get cache line sizes and _zva_length using same approach as Linux.
> ++ */
> + uint64_t ctr_el0;
> + uint64_t dczid_el0;
> + __asm__ (
>
--
wbr, Kirill
devel/jdk: aarch64 cpu info and hardware capablities