diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/aarch64/sysconf.c | 55 |
2 files changed, 59 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog index e1146baaee..d0ef94c3ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-11-03 Richard Henderson <rth@twiddle.net> + + * sysdeps/unix/sysv/linux/aarch64/sysconf.c: New file. + 2017-11-03 Szabolcs Nagy <szabolcs.nagy@arm.com> * sysdeps/aarch64/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Optimize. diff --git a/sysdeps/unix/sysv/linux/aarch64/sysconf.c b/sysdeps/unix/sysv/linux/aarch64/sysconf.c new file mode 100644 index 0000000000..30608dd82d --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/sysconf.c @@ -0,0 +1,55 @@ +/* Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <assert.h> +#include <stdbool.h> +#include <stdlib.h> +#include <unistd.h> + + +static long int linux_sysconf (int name); + +/* Get the value of the system variable NAME. */ +long int +__sysconf (int name) +{ + unsigned ctr; + + /* Unfortunately, the registers that contain the actual cache info + (CCSIDR_EL1, CLIDR_EL1, and CSSELR_EL1) are protected by the Linux + kernel (though they need not have been). However, CTR_EL0 contains + the *minimum* linesize in the entire cache hierarchy, and is + accessible to userland, for use in __aarch64_sync_cache_range, + and it is a reasonable assumption that the L1 cache will have that + minimum line size. */ + switch (name) + { + case _SC_LEVEL1_ICACHE_LINESIZE: + asm("mrs\t%0, ctr_el0" : "=r"(ctr)); + return 4 << (ctr & 0xf); + case _SC_LEVEL1_DCACHE_LINESIZE: + asm("mrs\t%0, ctr_el0" : "=r"(ctr)); + return 4 << ((ctr >> 16) & 0xf); + } + + return linux_sysconf (name); +} + +/* Now the generic Linux version. */ +#undef __sysconf +#define __sysconf static linux_sysconf +#include <sysdeps/unix/sysv/linux/sysconf.c> |