Page MenuHomeFreeBSD

Support HWCAP/HWCAP2 for 32-bit ARM binaries.
ClosedPublic

Authored by grehan on Wed, Jul 14, 8:51 AM.

Details

Summary

PR 256897

Test Plan
chroot into a 32-bit ARMv7 dist on a FreeBSD/arm64 system
and run 'procstat -x' to verify that HWCAP/HWCAP2 are present
in the aux array.

Tested with qemu-aarch64 with cortexA53 and A72 cpu types, and
also on AWS Graviton (backport to 13)

Diff Detail

Repository
R10 FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

manu added subscribers: cognet, mmel.

Thanks, that looks good at first glance.
I know that @mmel and @cognet where also interested in adding support for this so maybe wait for one of them to approve too.

This revision is now accepted and ready to land.Wed, Jul 14, 9:50 AM
sys/arm64/arm64/identcpu.c
1714

These registers could be different in a big.LITTLE system so we need a consistent view of them in user_cpu_desc and to use that here.

sys/arm64/arm64/identcpu.c
2098–2101

We should only read these if EL0 supports AArch32. The docs say direct access is unknown if no exception levels support AArch32, however I'm unsure if that means the values are unknown, or the hw could raise an exception.

sys/arm64/arm64/identcpu.c
1714

I'll fix that.

Will there ever be a big.LITTLE case where some PEs don't support EL0-32 ?

sys/arm64/arm64/identcpu.c
1714

I don't know of any current SoCs, however (based on what I've been told) there's a strong possibility in future SoCs.

jhb added inline comments.
sys/arm64/include/elf.h
152

This does raise the issue, btw, that 'cc -m32' probably doesn't work today on aarch64. For that to work, we'd need to merge the MD headers the way sys/x86/include works. However, we can tell people to setup a armv7 chroot and use --sysroot to point to that along with -m32 as a workaround. If we really care about freebsd32 on aarch64 we should figure out a solution for /usr/include/machine to support both eventually.

The approach looks good to me. I can't speak to the details of how the bits are set.

sys/arm64/include/elf.h
152

We decided a long time ago that we didn't care about that.
COMPAT32 is useful for poudriere support to build armv7 packages on bigger machine but apart from that I doubt that there is a real need.

fuz_fuz.su added a subscriber: fuz_fuz.su.

Patch successfully on arm64 13.0 RELEASE. Applying it makes armv7 Go binaries work.

Otherwise looks good for me.,

sys/arm64/arm64/identcpu.c
1728

state3 field of ID_PFR0_EL1 register is fixed to 0 by ARMv8 ARM, so this test is unnecessary

sys/arm64/include/elf.h
153

These comments should be changed to reflect ARMv8 reality.

  • Remove HWCAP32_THUMBEE as this is unused in ARMv8
  • Update COMPAT HWCAP comments to reflect ARMv8 usage.
This revision now requires review to proceed.Thu, Jul 15, 10:41 AM

A few comments on register macro names & values.

I've also created D31201 to rework how we set the HWCAPS values. I'm happy to move the 32-bit HWCAPS to that format based on this change after the register and HWCAP32* macros have been committed.

sys/arm64/include/armreg.h
774

We don't normally add _EL1 on these definitions

810

UL(0x01)

814

I've been following capitalisation from the documentation to help auto generate these registers so these would be ID_PFR0_State...

840

Maybe call this ID_PFR0_EL1_CSV2_HWCTX as later revisions of the architecture add a variant that branch targets trained on both different hardware contexts and different addresses can control speculative execution on different hardware contexts and addresses respectively.

856

FPShVec

857

UL(0x2)

898–899

Maybe MVFR1_SIMDHP_CONV (or _CONV_SP) and MVFR1_SIMDHP_ARITH so it's obvious the former only allows for conversion, while the latter adds arithmetic operations.

904–905

Maybe MVFR1_FPHP_CONV_SP and MVFR1_FPHP_CONV_DP and add MVFR1_FPHP_CONV_ARITH (UL(0x3)...) to indicate support for half-precision arithmetic operations.

Thanks: I'll pull in changes for this with the fix for checking caps across CPUs.

  • Remove HWCAP32_THUMBEE as this is unused in ARMv8
  • Update COMPAT HWCAP comments to reflect ARMv8 usage.
  • Print aarch32 regs, and compare across all CPUs.
  • Remove _EL1 from register defines.
  • Fix typo in ID_ISAR5_VCMA_IMPL constant.
  • FPshVec -> FPShVec in register defines.
  • Review feedback on register names

The register printing may be a bit verbose: feedback welcome.

AArch32 Instruction Set Attributes 5 = <CRC32,SHA2,SHA1,AES+VMULL>
AArch32 Media and VFP Features 0 = <FPRound,FPSqrt,FPDivide,DP VFPv3+v4,SP VFPv3+v4,AdvSIMD>
AArch32 Media and VFP Features 1 = <SIMDFMAC,FPHP DP Conv,SIMDHP SP Conv,SIMDSP,SIMDInt,SIMDLS,FPDNaN,FPFtZ>

The case of no EL0 32-bit should work, though untested.

Tested on a M1 Mac under Parallels:

AArch32 Instruction Set Attributes 5 = <SEVL Nop>
AArch32 Media and VFP Features 0 = <>
AArch32 Media and VFP Features 1 = <>
sys/arm64/arm64/identcpu.c
1037–1038

I would swap these so we print when SEVL is implemented, otherwise we print something when no 32-bit support is present.

This revision is now accepted and ready to land.Wed, Jul 21, 2:59 PM
  • Invert sense of SEVL printing.
This revision now requires review to proceed.Fri, Jul 23, 7:27 AM
This revision is now accepted and ready to land.Fri, Jul 23, 8:53 AM

Verified to build lang/go on a FreeBSD 13 AWS c6g.8xlarge in a poudriere armv7 jail with this patch applied to the kernel.