1251514Sandrew/*- 2251514Sandrew * Copyright (c) 2013 The NetBSD Foundation, Inc. 3251514Sandrew * Copyright (c) 2013 Andrew Turner 4251514Sandrew * All rights reserved. 5251514Sandrew * 6251514Sandrew * This code is derived from software contributed to The NetBSD Foundation 7251514Sandrew * by Matt Thomas of 3am Software Foundry. 8251514Sandrew * 9251514Sandrew * Redistribution and use in source and binary forms, with or without 10251514Sandrew * modification, are permitted provided that the following conditions 11251514Sandrew * are met: 12251514Sandrew * 1. Redistributions of source code must retain the above copyright 13251514Sandrew * notice, this list of conditions and the following disclaimer. 14251514Sandrew * 2. Redistributions in binary form must reproduce the above copyright 15251514Sandrew * notice, this list of conditions and the following disclaimer in the 16251514Sandrew * documentation and/or other materials provided with the distribution. 17251514Sandrew * 18251514Sandrew * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19251514Sandrew * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20251514Sandrew * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21251514Sandrew * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22251514Sandrew * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23251514Sandrew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24251514Sandrew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25251514Sandrew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26251514Sandrew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27251514Sandrew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28251514Sandrew * POSSIBILITY OF SUCH DAMAGE. 29251514Sandrew * 30251514Sandrew * Bases on NetBSD lib/libc/arch/arm/misc/arm_initfini.c 31251514Sandrew * $NetBSD: arm_initfini.c,v 1.2 2013/01/31 06:47:55 matt Exp $ 32251514Sandrew */ 33251514Sandrew 34251514Sandrew#include <sys/cdefs.h> 35251514Sandrew__FBSDID("$FreeBSD$"); 36251514Sandrew 37251514Sandrew/* 38251514Sandrew * To properly implement setjmp/longjmp for the ARM AAPCS ABI, it has to be 39251514Sandrew * aware of whether there is a FPU is present or not. Regardless of whether 40251514Sandrew * the hard-float ABI is being used, setjmp needs to save D8-D15. But it can 41251514Sandrew * only do this if those instructions won't cause an exception. 42251514Sandrew */ 43251514Sandrew 44251514Sandrew#include <sys/param.h> 45251514Sandrew#include <sys/sysctl.h> 46251514Sandrew 47251514Sandrew#include <stdbool.h> 48251514Sandrew#include <stddef.h> 49251514Sandrew 50251514Sandrewextern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 51251514Sandrew void *newp, size_t newlen); 52251514Sandrew 53251514Sandrewint _libc_arm_fpu_present; 54251514Sandrewstatic bool _libc_aapcs_initialized; 55251514Sandrew 56251514Sandrewvoid _libc_aapcs_init(void) __attribute__((__constructor__, __used__)); 57251514Sandrew 58251514Sandrewvoid 59251514Sandrew_libc_aapcs_init(void) 60251514Sandrew{ 61251514Sandrew int mib[2]; 62251514Sandrew size_t len; 63251514Sandrew 64251514Sandrew if (_libc_aapcs_initialized) 65251514Sandrew return; 66251514Sandrew 67251514Sandrew mib[0] = CTL_HW; 68251514Sandrew mib[1] = HW_FLOATINGPT; 69251514Sandrew 70251514Sandrew len = sizeof(_libc_arm_fpu_present); 71251514Sandrew if (__sysctl(mib, 2, &_libc_arm_fpu_present, &len, NULL, 0) == -1 || 72251514Sandrew len != sizeof(_libc_arm_fpu_present)) { 73251514Sandrew /* sysctl failed, assume no vfp */ 74251514Sandrew _libc_arm_fpu_present = 0; 75251514Sandrew } 76251514Sandrew 77251514Sandrew _libc_aapcs_initialized = true; 78251514Sandrew} 79