Summary: | 6926e26: arm: Add support for using VFP in kernel broke my kernel | ||||||
---|---|---|---|---|---|---|---|
Product: | Base System | Reporter: | crb <crb> | ||||
Component: | arm | Assignee: | Mark Johnston <markj> | ||||
Status: | Closed FIXED | ||||||
Severity: | Affects Some People | CC: | Andrew, bsd, markj, thoma555-bsd | ||||
Priority: | --- | Flags: | markj:
mfc-stable13-
|
||||
Version: | 14.0-STABLE | ||||||
Hardware: | arm | ||||||
OS: | Any | ||||||
Attachments: |
|
Description
crb
2023-09-13 06:24:09 UTC
I have been looking at this. The problem seems to be the code in sys/arm/arm/vfp.c expects the floating-point unit to be disabled on boot and expects the first floating-point operation to trap (?). Zynq chips boot with VFP enabled. If I disable the VFP by pausing in u-boot and writing 0 to the fpexc register (using Xilinx debugging tools), the kernel boots. I'm surprised this hasn't tripped up other armv7 boards. Thomas, This is super helpful, thank you! I'm not sure there is a good way to get u-boot to write 0 to the fpexc register but maybe I could hack that in and it would get me running at least. Is there a way to make FreeBSD not make the assumption or handle correctly the case where it's wrong? What do you think is the right way to fix this? Thanks, Christopher (In reply to crb from comment #2) The arm64 version of vfp.c disables the vfp with a call to vfp_disable() in vfp_init() with the comment "/* Disable to be enabled when it's used */". Doing the same in the armv7 version fixes the problem but I am concerned that vfp_disable() would be called again for each CPU when it appears the fpexc register is not a per-CPU register. In other words, I am not confident that I know how this is supposed to work. Thomas, Again, thank you for looking at all this, I'm not sure I would have figured it out on my own. I wonder if u-boot for other ARMv7 board isn't turning this off before handing over to the kernel? Is there any reason not to simply clear this bit in lowcore.s or some other similar early boot place? Thanks again, Christopher (In reply to Thomas Skibo from comment #3) Why do you think it's not per-CPU? vfp_disable will need to work per-CPU otherwise the current VFP handling will be broken as we disable the VFP in the same way at the end of vfp_store. Created attachment 244904 [details]
Possible fix to 273752
(In reply to Andrew Turner from comment #5) I think I was using the Xilinx debug tool (xsdb) incorrectly and it led me to believe fpexc only existed on CPU #0. I posted a possible fix in which vfp_disable() is called in vfp_init() for each CPU. Let me know what you think. (In reply to Thomas Skibo from comment #6) For me, this patch seems to solve the issue, I can boot now with kernel based on sources from September 1st, 2023 on Zybo Z7 board. Thanks. This also allows me to build and boot a recent kernel. Thank you so much Thomas! Is there any possibility we can get this in for 14.0? 14 may be the last version that supports 32 machines (at least if my kernel warning is to be believed) and it would be nice to have that last release working on 32 machines before we abondon them. Thanks Christopher (In reply to Andrew Turner from comment #5) Do you see any reason not to commit the patch from comment 6? The patch looks correct so should be committed. (In reply to Thomas Skibo from comment #7) In the absence of a commit message, I wrote one. If this looks ok to you I'll push to main: commit 4c93213d5345306810a5f2ac272cd8a2703684af (HEAD -> main) Author: Thomas Skibo <thomas-bsd@skibo.net> Date: Mon Oct 2 11:58:54 2023 -0400 arm: Disable the VFP during boot The VFP code expects the kernel to boot with VFP disabled, but some boards will boot with it enabled. Make sure that vfp_init() disables the VFP on each CPU during boot. PR: 273752 Reviewed by: andrew, markj MFC after: 1 week diff --git a/sys/arm/arm/vfp.c b/sys/arm/arm/vfp.c index 40a3491c1cf9..d043f89a7e34 100644 --- a/sys/arm/arm/vfp.c +++ b/sys/arm/arm/vfp.c @@ -180,6 +180,9 @@ vfp_init(void) elf_hwcap |= HWCAP_VFPv4; } + /* Disable to be enabled when it's used */ + vfp_disable(); + /* initialize the coprocess 10 and 11 calls * These are called to restore the registers and enable * the VFP hardware. A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=ce2f34ade8b787b068085fa8a8ddd295b06c2737 commit ce2f34ade8b787b068085fa8a8ddd295b06c2737 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2023-12-11 14:08:49 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2023-12-11 14:08:49 +0000 arm: Disable the VFP during boot The VFP code expects the kernel to boot with VFP disabled, but some boards will boot with it enabled. Make sure that vfp_init() disables the VFP on each CPU during boot. PR: 273752 Reviewed by: andrew Diagnosed by: Thomas Skibo <thomas-bsd@skibo.net> MFC after: 1 week sys/arm/arm/vfp.c | 2 ++ 1 file changed, 2 insertions(+) A commit in branch stable/14 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=f5ae760cfe2658d79f12c1b7ac9dc577379e5d1c commit f5ae760cfe2658d79f12c1b7ac9dc577379e5d1c Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2023-12-11 14:08:49 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2023-12-18 02:07:49 +0000 arm: Disable the VFP during boot The VFP code expects the kernel to boot with VFP disabled, but some boards will boot with it enabled. Make sure that vfp_init() disables the VFP on each CPU during boot. PR: 273752 Reviewed by: andrew Diagnosed by: Thomas Skibo <thomas-bsd@skibo.net> MFC after: 1 week (cherry picked from commit ce2f34ade8b787b068085fa8a8ddd295b06c2737) sys/arm/arm/vfp.c | 2 ++ 1 file changed, 2 insertions(+) ^Triage: assign to committer that resolved and fiddle with metadata. I believe there's nothing left to commit here, please re-open if I'm mistaken. |