diff options
author | Richard Henderson <rth@twiddle.net> | 2017-11-03 16:38:16 +0000 |
---|---|---|
committer | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2017-11-03 16:40:27 +0000 |
commit | 6d58ce5e5072945d44f2dba83ad16cd6febd056c (patch) | |
tree | 35cd666ef3c3feb4130d963d08620734ef4bc51c /sysdeps/unix/sysv/linux | |
parent | 659ca267360e1c1f64eea9205bb81cb5e9049908 (diff) | |
download | glibc-6d58ce5e5072945d44f2dba83ad16cd6febd056c.tar.gz glibc-6d58ce5e5072945d44f2dba83ad16cd6febd056c.tar.xz glibc-6d58ce5e5072945d44f2dba83ad16cd6febd056c.zip |
aarch64: Guess L1 cache linesize for aarch64
Using the cache hierarchy linesize minimum in CTR_EL0. See the comment within the code for rationale. * sysdeps/unix/sysv/linux/aarch64/sysconf.c: New file.
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r-- | sysdeps/unix/sysv/linux/aarch64/sysconf.c | 55 |
1 files changed, 55 insertions, 0 deletions
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> |