/* x86_64 cache info.
Copyright (C) 2003-2013 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>
#include <cpuid.h>
#ifndef __cpuid_count
/* FIXME: Provide __cpuid_count if it isn't defined. Copied from gcc
4.4.0. Remove this if gcc 4.4 is the minimum requirement. */
# if defined(__i386__) && defined(__PIC__)
/* %ebx may be the PIC register. */
# define __cpuid_count(level, count, a, b, c, d) \
__asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \
"cpuid\n\t" \
"xchg{l}\t{%%}ebx, %1\n\t" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (level), "2" (count))
# else
# define __cpuid_count(level, count, a, b, c, d) \
__asm__ ("cpuid\n\t" \
: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
: "0" (level), "2" (count))
# endif
#endif
#ifdef USE_MULTIARCH
# include "multiarch/init-arch.h"
# define is_intel __cpu_features.kind == arch_kind_intel
# define is_amd __cpu_features.kind == arch_kind_amd
# define max_cpuid __cpu_features.max_cpuid
#else
/* This spells out "GenuineIntel". */
# define is_intel \
ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69
/* This spells out "AuthenticAMD". */
# define is_amd \
ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65
#endif
static const struct intel_02_cache_info
{
unsigned char idx;
unsigned char assoc;
unsigned char linesize;
unsigned char rel_name;
unsigned int size;
} intel_02_known [] =
{
#define M(sc) ((sc) - _SC_LEVEL1_ICACHE_SIZE)
{ 0x06, 4, 32, M(_SC_LEVEL1_ICACHE_SIZE), 8192 },
{ 0x08, 4, 32, M(_SC_LEVEL1_ICACHE_SIZE), 16384 },
{ 0x09, 4, 32, M(_SC_LEVEL1_ICACHE_SIZE), 32768 },
{ 0x0a, 2, 32, M(_SC_LEVEL1_DCACHE_SIZE), 8192 },
{ 0x0c, 4, 32, M(_SC_LEVEL1_DCACHE_SIZE), 16384 },
{ 0x0d, 4, 64, M(_SC_LEVEL1_DCACHE_SIZE), 16384 },
{ 0x0e, 6, 64, M(_SC_LEVEL1_DCACHE_SIZE), 24576 },
{ 0x21, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 262144 },
{ 0x22, 4, 64, M(_SC_LEVEL3_CACHE_SIZE), 524288 },
{ 0x23, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 1048576 },
{ 0x25, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 2097152 },
{ 0x29, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 4194304 },
{