17862701c0e3f556e4a0c7ec4074a40526c73a4efflorian/* -*- mode: C; c-basic-offset: 3; -*- */ 2b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 3b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote/*--------------------------------------------------------------------*/ 47862701c0e3f556e4a0c7ec4074a40526c73a4efflorian/*--- Cache-related stuff. m_cache.c ---*/ 5b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote/*--------------------------------------------------------------------*/ 6b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 7b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote/* 87862701c0e3f556e4a0c7ec4074a40526c73a4efflorian This file is part of Valgrind, a dynamic binary instrumentation 97862701c0e3f556e4a0c7ec4074a40526c73a4efflorian framework. 10b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 11b3a1e4bffbdbbf38304f216af405009868f43628sewardj Copyright (C) 2002-2015 Nicholas Nethercote 122bc10126a94b421a490b2759dc50ab67ec4ee116njn njn@valgrind.org 13b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 14b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote This program is free software; you can redistribute it and/or 15b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote modify it under the terms of the GNU General Public License as 16b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote published by the Free Software Foundation; either version 2 of the 17b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote License, or (at your option) any later version. 18b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 19b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote This program is distributed in the hope that it will be useful, but 20b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote WITHOUT ANY WARRANTY; without even the implied warranty of 21b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote General Public License for more details. 23b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 24b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote You should have received a copy of the GNU General Public License 25b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote along with this program; if not, write to the Free Software 26b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 02111-1307, USA. 28b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 29b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote The GNU General Public License is contained in the file COPYING. 30b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote*/ 31b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 327862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#include "pub_core_basics.h" 337862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#include "pub_core_libcbase.h" 347862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#include "pub_core_libcassert.h" 357862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#include "pub_core_libcprint.h" 367862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#include "pub_core_mallocfree.h" 377862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#include "pub_core_machine.h" 3838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#include "pub_core_debuglog.h" 397862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#include "libvex.h" 408b68b64759254d514d98328c496cbd88cde4c9a5njn 417862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#if defined(VGA_x86) || defined(VGA_amd64) 42c7561b931e249acf3768ead77638545b0ccaa8f1njn 437862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#include "pub_core_cpuid.h" 44b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 45f91b0a372a0d0cb4030b096337d3c1ebe26d6b30sewardj// All CPUID info taken from sandpile.org/ia32/cpuid.htm */ 46b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote// Probably only works for Intel and AMD chips, and probably only for some of 477862701c0e3f556e4a0c7ec4074a40526c73a4efflorian// them. 48b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 4938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianstatic void 5038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianadd_cache(VexCacheInfo *ci, VexCache cache) 51b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote{ 5238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian static UInt num_allocated = 0; 5338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 5438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian if (ci->num_caches == num_allocated) { 5538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian num_allocated += 6; 5638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian ci->caches = VG_(realloc)("m_cache", ci->caches, 5738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian num_allocated * sizeof *ci->caches); 5838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 5938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 6038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian if (ci->num_levels < cache.level) ci->num_levels = cache.level; 6138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian ci->caches[ci->num_caches++] = cache; 62b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote} 63b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 6438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian/* Convenience macros */ 6538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_icache(level, size, assoc, linesize) \ 6638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian do { \ 6738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian add_cache(ci, \ 6838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VEX_CACHE_INIT(INSN_CACHE, level, size, linesize, assoc)); \ 6938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } while (0) 7038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 7138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_dcache(level, size, assoc, linesize) \ 7238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian do { \ 7338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian add_cache(ci, \ 7438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VEX_CACHE_INIT(DATA_CACHE, level, size, linesize, assoc)); \ 7538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } while (0) 7638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 7738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_ucache(level, size, assoc, linesize) \ 7838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian do { \ 7938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian add_cache(ci, \ 8038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VEX_CACHE_INIT(UNIFIED_CACHE, level, size, linesize, assoc)); \ 8138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } while (0) 8238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 8338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_itcache(level, size, assoc) \ 8438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian do { \ 8538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VexCache c = \ 8638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VEX_CACHE_INIT(INSN_CACHE, level, size, 0, assoc); \ 8738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian c.is_trace_cache = True; \ 8838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian add_cache(ci, c); \ 8938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } while (0) 9038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 9138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_I1(size, assoc, linesize) add_icache(1, size, assoc, linesize) 9238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_D1(size, assoc, linesize) add_dcache(1, size, assoc, linesize) 9338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_U1(size, assoc, linesize) add_ucache(1, size, assoc, linesize) 9438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_I2(size, assoc, linesize) add_icache(2, size, assoc, linesize) 9538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_D2(size, assoc, linesize) add_dcache(2, size, assoc, linesize) 9638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_U2(size, assoc, linesize) add_ucache(2, size, assoc, linesize) 9738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_I3(size, assoc, linesize) add_icache(3, size, assoc, linesize) 9838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_D3(size, assoc, linesize) add_dcache(3, size, assoc, linesize) 9938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_U3(size, assoc, linesize) add_ucache(3, size, assoc, linesize) 10038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 10138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian#define add_I1T(size, assoc) \ 10238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian add_itcache(1, size, assoc) 1037862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 104b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote/* Intel method is truly wretched. We have to do an insane indexing into an 105b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * array of pre-defined configurations for various parts of the memory 1061c3e3c5f51bfea566a55024fe2ef4c1eb3d47265weidendo * hierarchy. 1071c3e3c5f51bfea566a55024fe2ef4c1eb3d47265weidendo * According to Intel Processor Identification, App Note 485. 1087862701c0e3f556e4a0c7ec4074a40526c73a4efflorian * 1092d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn * If a L3 cache is found, then data for it rather than the L2 1102d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn * is returned via *LLc. 111b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote */ 1127862701c0e3f556e4a0c7ec4074a40526c73a4efflorianstatic Int 11338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianIntel_cache_info(Int level, VexCacheInfo *ci) 114b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote{ 11594830f470f13df0fcd92bc57bdf312b4716eca31florian UInt cpuid1_eax; 11694830f470f13df0fcd92bc57bdf312b4716eca31florian UInt cpuid1_ignore; 1171c3e3c5f51bfea566a55024fe2ef4c1eb3d47265weidendo Int family; 1181c3e3c5f51bfea566a55024fe2ef4c1eb3d47265weidendo Int model; 119b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote UChar info[16]; 120ad8a591c92e1003de859735c77c9474a53b90e31tom Int i, j, trials; 121b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 122b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote if (level < 2) { 12338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", "warning: CPUID level < 2 for Intel " 12438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "processor (%d)\n", level); 125b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote return -1; 126b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote } 127b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 1281c3e3c5f51bfea566a55024fe2ef4c1eb3d47265weidendo /* family/model needed to distinguish code reuse (currently 0x49) */ 129ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(1, 0, &cpuid1_eax, &cpuid1_ignore, 1301c3e3c5f51bfea566a55024fe2ef4c1eb3d47265weidendo &cpuid1_ignore, &cpuid1_ignore); 1311c3e3c5f51bfea566a55024fe2ef4c1eb3d47265weidendo family = (((cpuid1_eax >> 20) & 0xff) << 4) + ((cpuid1_eax >> 8) & 0xf); 1321c3e3c5f51bfea566a55024fe2ef4c1eb3d47265weidendo model = (((cpuid1_eax >> 16) & 0xf) << 4) + ((cpuid1_eax >> 4) & 0xf); 1331c3e3c5f51bfea566a55024fe2ef4c1eb3d47265weidendo 13494830f470f13df0fcd92bc57bdf312b4716eca31florian VG_(cpuid)(2, 0, (UInt*)&info[0], (UInt*)&info[4], 13594830f470f13df0fcd92bc57bdf312b4716eca31florian (UInt*)&info[8], (UInt*)&info[12]); 136b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote trials = info[0] - 1; /* AL register - bits 0..7 of %eax */ 137b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote info[0] = 0x0; /* reset AL */ 138b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 139b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote if (0 != trials) { 14038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", "warning: non-zero CPUID trials for Intel " 14138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "processor (%d)\n", trials); 142b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote return -1; 143b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote } 144b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 14538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian ci->num_levels = 0; 14638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian ci->num_caches = 0; 14738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian ci->icaches_maintain_coherence = True; 14838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian ci->caches = NULL; 14938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 150b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote for (i = 0; i < 16; i++) { 151b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 152b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote switch (info[i]) { 153b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 154b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote case 0x0: /* ignore zeros */ 155b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote break; 1567862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 157b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote /* TLB info, ignore */ 158966b5bdf999d797ccdf924f03923a9ddb6c8dcd4weidendo case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: 159ca7cf38b6e9742dccc286d4065a07ff7f588cd88weidendo case 0x0b: 16055b3a81eb11694b1140cad698af66ee28e03db61tom case 0x4f: case 0x50: case 0x51: case 0x52: case 0x55: 1611e76ff5eeeb2e918b3896c3aaab83ee141e30285tom case 0x56: case 0x57: case 0x59: 16255b3a81eb11694b1140cad698af66ee28e03db61tom case 0x5a: case 0x5b: case 0x5c: case 0x5d: 163ca7cf38b6e9742dccc286d4065a07ff7f588cd88weidendo case 0x76: 16455b3a81eb11694b1140cad698af66ee28e03db61tom case 0xb0: case 0xb1: case 0xb2: 1651e76ff5eeeb2e918b3896c3aaab83ee141e30285tom case 0xb3: case 0xb4: case 0xba: case 0xc0: 16655b3a81eb11694b1140cad698af66ee28e03db61tom case 0xca: 1677862701c0e3f556e4a0c7ec4074a40526c73a4efflorian break; 168b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 16938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x06: add_I1( 8, 4, 32); break; 17038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x08: add_I1(16, 4, 32); break; 17138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x09: add_I1(32, 4, 64); break; 17238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x30: add_I1(32, 8, 64); break; 173b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 17438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x0a: add_D1( 8, 2, 32); break; 17538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x0c: add_D1(16, 4, 32); break; 17638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x0d: add_D1(16, 4, 64); break; 17738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x0e: add_D1(24, 6, 64); break; 17838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x2c: add_D1(32, 8, 64); break; 179b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 180b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote /* IA-64 info -- panic! */ 1817862701c0e3f556e4a0c7ec4074a40526c73a4efflorian case 0x10: case 0x15: case 0x1a: 182b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote case 0x88: case 0x89: case 0x8a: case 0x8d: 183b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote case 0x90: case 0x96: case 0x9b: 1847862701c0e3f556e4a0c7ec4074a40526c73a4efflorian VG_(core_panic)("IA-64 cache detected?!"); 185b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 1862d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn /* L3 cache info. */ 18738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x22: add_U3(512, 4, 64); break; 18838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x23: add_U3(1024, 8, 64); break; 18938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x25: add_U3(2048, 8, 64); break; 19038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x29: add_U3(4096, 8, 64); break; 19138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x46: add_U3(4096, 4, 64); break; 19238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x47: add_U3(8192, 8, 64); break; 19338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x4a: add_U3(6144, 12, 64); break; 19438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x4b: add_U3(8192, 16, 64); break; 19538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x4c: add_U3(12288, 12, 64); break; 19638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x4d: add_U3(16384, 16, 64); break; 19738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xd0: add_U3(512, 4, 64); break; 19838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xd1: add_U3(1024, 4, 64); break; 19938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xd2: add_U3(2048, 4, 64); break; 20038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xd6: add_U3(1024, 8, 64); break; 20138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xd7: add_U3(2048, 8, 64); break; 20238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xd8: add_U3(4096, 8, 64); break; 20338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xdc: add_U3(1536, 12, 64); break; 20438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xdd: add_U3(3072, 12, 64); break; 20538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xde: add_U3(6144, 12, 64); break; 20638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xe2: add_U3(2048, 16, 64); break; 20738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xe3: add_U3(4096, 16, 64); break; 20838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xe4: add_U3(8192, 16, 64); break; 20938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xea: add_U3(12288, 24, 64); break; 21038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xeb: add_U3(18432, 24, 64); break; 21138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0xec: add_U3(24576, 24, 64); break; 212b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 21355b3a81eb11694b1140cad698af66ee28e03db61tom /* Described as "MLC" in Intel documentation */ 21438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x21: add_U2(256, 8, 64); break; 21555b3a81eb11694b1140cad698af66ee28e03db61tom 216b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote /* These are sectored, whatever that means */ 21738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian // FIXME: I did not find these in the Intel docs 21838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x39: add_U2(128, 4, 64); break; 21938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x3c: add_U2(256, 4, 64); break; 220b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 2217862701c0e3f556e4a0c7ec4074a40526c73a4efflorian /* If a P6 core, this means "no L2 cache". 222b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote If a P4 core, this means "no L3 cache". 223b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote We don't know what core it is, so don't issue a warning. To detect 224b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote a missing L2 cache, we use 'L2_found'. */ 225b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote case 0x40: 226b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote break; 227b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 22838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x41: add_U2( 128, 4, 32); break; 22938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x42: add_U2( 256, 4, 32); break; 23038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x43: add_U2( 512, 4, 32); break; 23138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x44: add_U2( 1024, 4, 32); break; 23238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x45: add_U2( 2048, 4, 32); break; 23338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x48: add_U2( 3072, 12, 64); break; 23438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x4e: add_U2( 6144, 24, 64); break; 2351c3e3c5f51bfea566a55024fe2ef4c1eb3d47265weidendo case 0x49: 2362d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn if (family == 15 && model == 6) { 2372d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn /* On Xeon MP (family F, model 6), this is for L3 */ 23838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian add_U3(4096, 16, 64); 2392d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn } else { 24038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian add_U2(4096, 16, 64); 2412d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn } 2422d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn break; 243b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 244b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote /* These are sectored, whatever that means */ 24538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x60: add_D1(16, 8, 64); break; /* sectored */ 24638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x66: add_D1( 8, 4, 64); break; /* sectored */ 24738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x67: add_D1(16, 4, 64); break; /* sectored */ 24838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x68: add_D1(32, 4, 64); break; /* sectored */ 249b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 250b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote /* HACK ALERT: Instruction trace cache -- capacity is micro-ops based. 251b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * conversion to byte size is a total guess; treat the 12K and 16K 252b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * cases the same since the cache byte size must be a power of two for 2537862701c0e3f556e4a0c7ec4074a40526c73a4efflorian * everything to work!. Also guessing 32 bytes for the line size... 254b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote */ 255b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote case 0x70: /* 12K micro-ops, 8-way */ 25638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian add_I1T(12, 8); 2577862701c0e3f556e4a0c7ec4074a40526c73a4efflorian break; 258b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote case 0x71: /* 16K micro-ops, 8-way */ 25938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian add_I1T(16, 8); 2607862701c0e3f556e4a0c7ec4074a40526c73a4efflorian break; 261b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote case 0x72: /* 32K micro-ops, 8-way */ 26238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian add_I1T(32, 8); 2637862701c0e3f556e4a0c7ec4074a40526c73a4efflorian break; 264b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 265f91b0a372a0d0cb4030b096337d3c1ebe26d6b30sewardj /* not sectored, whatever that might mean */ 26638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x78: add_U2(1024, 4, 64); break; 267f91b0a372a0d0cb4030b096337d3c1ebe26d6b30sewardj 268b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote /* These are sectored, whatever that means */ 26938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x79: add_U2( 128, 8, 64); break; 27038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x7a: add_U2( 256, 8, 64); break; 27138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x7b: add_U2( 512, 8, 64); break; 27238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x7c: add_U2(1024, 8, 64); break; 27338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x7d: add_U2(2048, 8, 64); break; 27438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x7e: add_U2( 256, 8, 128); break; 27538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x7f: add_U2( 512, 2, 64); break; 27638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x80: add_U2( 512, 8, 64); break; 27738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x81: add_U2( 128, 8, 32); break; 27838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x82: add_U2( 256, 8, 32); break; 27938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x83: add_U2( 512, 8, 32); break; 28038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x84: add_U2(1024, 8, 32); break; 28138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x85: add_U2(2048, 8, 32); break; 28238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x86: add_U2( 512, 4, 64); break; 28338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 0x87: add_U2(1024, 8, 64); break; 284b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 285942d9efe96b793d25cc2a647e4a06eb496b6d120tom /* Ignore prefetch information */ 286942d9efe96b793d25cc2a647e4a06eb496b6d120tom case 0xf0: case 0xf1: 2876f74a7ef1768dd3925cc22869b4e5e24e9338d08njn break; 288942d9efe96b793d25cc2a647e4a06eb496b6d120tom 289ad8a591c92e1003de859735c77c9474a53b90e31tom case 0xff: 290ad8a591c92e1003de859735c77c9474a53b90e31tom j = 0; 29194830f470f13df0fcd92bc57bdf312b4716eca31florian VG_(cpuid)(4, j++, (UInt*)&info[0], (UInt*)&info[4], 29294830f470f13df0fcd92bc57bdf312b4716eca31florian (UInt*)&info[8], (UInt*)&info[12]); 293ad8a591c92e1003de859735c77c9474a53b90e31tom 294ad8a591c92e1003de859735c77c9474a53b90e31tom while ((info[0] & 0x1f) != 0) { 295ad8a591c92e1003de859735c77c9474a53b90e31tom UInt assoc = ((*(UInt *)&info[4] >> 22) & 0x3ff) + 1; 296ad8a591c92e1003de859735c77c9474a53b90e31tom UInt parts = ((*(UInt *)&info[4] >> 12) & 0x3ff) + 1; 297ad8a591c92e1003de859735c77c9474a53b90e31tom UInt line_size = (*(UInt *)&info[4] & 0x7ff) + 1; 298ad8a591c92e1003de859735c77c9474a53b90e31tom UInt sets = *(UInt *)&info[8] + 1; 299ad8a591c92e1003de859735c77c9474a53b90e31tom 30038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian UInt size = assoc * parts * line_size * sets / 1024; 301ad8a591c92e1003de859735c77c9474a53b90e31tom 302ad8a591c92e1003de859735c77c9474a53b90e31tom switch ((info[0] & 0xe0) >> 5) 303ad8a591c92e1003de859735c77c9474a53b90e31tom { 304ad8a591c92e1003de859735c77c9474a53b90e31tom case 1: 305ad8a591c92e1003de859735c77c9474a53b90e31tom switch (info[0] & 0x1f) 306ad8a591c92e1003de859735c77c9474a53b90e31tom { 30738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 1: add_D1(size, assoc, line_size); break; 30838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 2: add_I1(size, assoc, line_size); break; 30938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 3: add_U1(size, assoc, line_size); break; 3107862701c0e3f556e4a0c7ec4074a40526c73a4efflorian default: 31138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", 31238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "warning: L1 cache of unknown type ignored\n"); 3137862701c0e3f556e4a0c7ec4074a40526c73a4efflorian break; 314ad8a591c92e1003de859735c77c9474a53b90e31tom } 315ad8a591c92e1003de859735c77c9474a53b90e31tom break; 316ad8a591c92e1003de859735c77c9474a53b90e31tom case 2: 317ad8a591c92e1003de859735c77c9474a53b90e31tom switch (info[0] & 0x1f) 318ad8a591c92e1003de859735c77c9474a53b90e31tom { 31938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 1: add_D2(size, assoc, line_size); break; 32038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 2: add_I2(size, assoc, line_size); break; 32138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 3: add_U2(size, assoc, line_size); break; 3227862701c0e3f556e4a0c7ec4074a40526c73a4efflorian default: 32338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", 32438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "warning: L2 cache of unknown type ignored\n"); 3257862701c0e3f556e4a0c7ec4074a40526c73a4efflorian break; 326ad8a591c92e1003de859735c77c9474a53b90e31tom } 327ad8a591c92e1003de859735c77c9474a53b90e31tom break; 328ad8a591c92e1003de859735c77c9474a53b90e31tom case 3: 329ad8a591c92e1003de859735c77c9474a53b90e31tom switch (info[0] & 0x1f) 330ad8a591c92e1003de859735c77c9474a53b90e31tom { 33138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 1: add_D3(size, assoc, line_size); break; 33238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 2: add_I3(size, assoc, line_size); break; 33338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case 3: add_U3(size, assoc, line_size); break; 3347862701c0e3f556e4a0c7ec4074a40526c73a4efflorian default: 33538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", 33638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "warning: L3 cache of unknown type ignored\n"); 3377862701c0e3f556e4a0c7ec4074a40526c73a4efflorian break; 338ad8a591c92e1003de859735c77c9474a53b90e31tom } 339ad8a591c92e1003de859735c77c9474a53b90e31tom break; 340ad8a591c92e1003de859735c77c9474a53b90e31tom default: 34138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", "warning: L%u cache ignored\n", 34238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian (info[0] & 0xe0) >> 5); 343ad8a591c92e1003de859735c77c9474a53b90e31tom break; 344ad8a591c92e1003de859735c77c9474a53b90e31tom } 345ad8a591c92e1003de859735c77c9474a53b90e31tom 34694830f470f13df0fcd92bc57bdf312b4716eca31florian VG_(cpuid)(4, j++, (UInt*)&info[0], (UInt*)&info[4], 34794830f470f13df0fcd92bc57bdf312b4716eca31florian (UInt*)&info[8], (UInt*)&info[12]); 348ad8a591c92e1003de859735c77c9474a53b90e31tom } 349ad8a591c92e1003de859735c77c9474a53b90e31tom break; 350ad8a591c92e1003de859735c77c9474a53b90e31tom 351b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote default: 35238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", 35338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "warning: Unknown Intel cache config value (0x%x), " 35438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "ignoring\n", info[i]); 3556f74a7ef1768dd3925cc22869b4e5e24e9338d08njn break; 356b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote } 357b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote } 358b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 359b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote return 0; 360b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote} 361b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 362b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote/* AMD method is straightforward, just extract appropriate bits from the 363b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * result registers. 364b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * 365b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * Bits, for D1 and I1: 3667862701c0e3f556e4a0c7ec4074a40526c73a4efflorian * 31..24 data L1 cache size in KBs 3677862701c0e3f556e4a0c7ec4074a40526c73a4efflorian * 23..16 data L1 cache associativity (FFh=full) 3687862701c0e3f556e4a0c7ec4074a40526c73a4efflorian * 15.. 8 data L1 cache lines per tag 369b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * 7.. 0 data L1 cache line size in bytes 370b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * 371b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * Bits, for L2: 372b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * 31..16 unified L2 cache size in KBs 373b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * 15..12 unified L2 cache associativity (0=off, FFh=full) 3747862701c0e3f556e4a0c7ec4074a40526c73a4efflorian * 11.. 8 unified L2 cache lines per tag 375b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * 7.. 0 unified L2 cache line size in bytes 376b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * 3777862701c0e3f556e4a0c7ec4074a40526c73a4efflorian * #3 The AMD K7 processor's L2 cache must be configured prior to relying 378b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * upon this information. (Whatever that means -- njn) 379b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * 380b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * Also, according to Cyrille Chepelov, Duron stepping A0 processors (model 381b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * 0x630) have a bug and misreport their L2 size as 1KB (it's really 64KB), 382b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote * so we detect that. 3837862701c0e3f556e4a0c7ec4074a40526c73a4efflorian * 3842d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn * Returns 0 on success, non-zero on failure. As with the Intel code 3852d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn * above, if a L3 cache is found, then data for it rather than the L2 3862d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn * is returned via *LLc. 387b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote */ 3882d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn 3892d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn/* A small helper */ 3907862701c0e3f556e4a0c7ec4074a40526c73a4efflorianstatic Int 3917862701c0e3f556e4a0c7ec4074a40526c73a4effloriandecode_AMD_cache_L2_L3_assoc ( Int bits_15_12 ) 3922d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn{ 3932d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn /* Decode a L2/L3 associativity indication. It is encoded 3942d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn differently from the I1/D1 associativity. Returns 1 3952d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn (direct-map) as a safe but suboptimal result for unknown 3962d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn encodings. */ 3972d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn switch (bits_15_12 & 0xF) { 3982d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn case 1: return 1; case 2: return 2; 3992d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn case 4: return 4; case 6: return 8; 4002d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn case 8: return 16; case 0xA: return 32; 4012d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn case 0xB: return 48; case 0xC: return 64; 4022d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn case 0xD: return 96; case 0xE: return 128; 4032d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn case 0xF: /* fully associative */ 4042d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn case 0: /* L2/L3 cache or TLB is disabled */ 4052d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn default: 4062d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn return 1; 4072d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn } 4082d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn} 4092d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn 4107862701c0e3f556e4a0c7ec4074a40526c73a4efflorianstatic Int 4117862701c0e3f556e4a0c7ec4074a40526c73a4efflorianAMD_cache_info(VexCacheInfo *ci) 412b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote{ 413b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote UInt ext_level; 414b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote UInt dummy, model; 4152d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn UInt I1i, D1i, L2i, L3i; 4167862701c0e3f556e4a0c7ec4074a40526c73a4efflorian UInt size, line_size, assoc; 4177862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 418ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(0x80000000, 0, &ext_level, &dummy, &dummy, &dummy); 419b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 420b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote if (0 == (ext_level & 0x80000000) || ext_level < 0x80000006) { 42138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", "warning: ext_level < 0x80000006 for AMD " 42238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "processor (0x%x)\n", ext_level); 423b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote return -1; 424b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote } 425b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 426ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(0x80000005, 0, &dummy, &dummy, &D1i, &I1i); 427ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(0x80000006, 0, &dummy, &dummy, &L2i, &L3i); 428b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 429ad8a591c92e1003de859735c77c9474a53b90e31tom VG_(cpuid)(0x1, 0, &model, &dummy, &dummy, &dummy); 430b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 431b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote /* Check for Duron bug */ 432b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote if (model == 0x630) { 43338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", "warning: Buggy Duron stepping A0. " 43438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "Assuming L2 size=65536 bytes\n"); 435b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote L2i = (64 << 16) | (L2i & 0xffff); 436b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote } 437b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 4387862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->num_levels = 2; 4397862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->num_caches = 3; 4407862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->icaches_maintain_coherence = True; 4417862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 4427862701c0e3f556e4a0c7ec4074a40526c73a4efflorian /* Check for L3 cache */ 4437862701c0e3f556e4a0c7ec4074a40526c73a4efflorian if (((L3i >> 18) & 0x3fff) > 0) { 4447862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->num_levels = 3; 4457862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->num_caches = 4; 4467862701c0e3f556e4a0c7ec4074a40526c73a4efflorian } 4477862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 4487862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->caches = VG_(malloc)("m_cache", ci->num_caches * sizeof *ci->caches); 4497862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 4507862701c0e3f556e4a0c7ec4074a40526c73a4efflorian // D1 4517862701c0e3f556e4a0c7ec4074a40526c73a4efflorian size = (D1i >> 24) & 0xff; 4527862701c0e3f556e4a0c7ec4074a40526c73a4efflorian assoc = (D1i >> 16) & 0xff; 4537862701c0e3f556e4a0c7ec4074a40526c73a4efflorian line_size = (D1i >> 0) & 0xff; 4547862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->caches[0] = VEX_CACHE_INIT(DATA_CACHE, 1, size, line_size, assoc); 455b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 4567862701c0e3f556e4a0c7ec4074a40526c73a4efflorian // I1 4577862701c0e3f556e4a0c7ec4074a40526c73a4efflorian size = (I1i >> 24) & 0xff; 4587862701c0e3f556e4a0c7ec4074a40526c73a4efflorian assoc = (I1i >> 16) & 0xff; 4597862701c0e3f556e4a0c7ec4074a40526c73a4efflorian line_size = (I1i >> 0) & 0xff; 4607862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->caches[1] = VEX_CACHE_INIT(INSN_CACHE, 1, size, line_size, assoc); 461b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 4627862701c0e3f556e4a0c7ec4074a40526c73a4efflorian // L2 Nb: different bits used for L2 4637862701c0e3f556e4a0c7ec4074a40526c73a4efflorian size = (L2i >> 16) & 0xffff; 4647862701c0e3f556e4a0c7ec4074a40526c73a4efflorian assoc = decode_AMD_cache_L2_L3_assoc((L2i >> 12) & 0xf); 4657862701c0e3f556e4a0c7ec4074a40526c73a4efflorian line_size = (L2i >> 0) & 0xff; 46638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian ci->caches[2] = VEX_CACHE_INIT(UNIFIED_CACHE, 2, size, line_size, assoc); 4672d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn 4687862701c0e3f556e4a0c7ec4074a40526c73a4efflorian // L3, if any 4692d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn if (((L3i >> 18) & 0x3fff) > 0) { 4707862701c0e3f556e4a0c7ec4074a40526c73a4efflorian /* There's an L3 cache. */ 4712d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn /* NB: the test in the if is "if L3 size > 0 ". I don't know if 4722d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn this is the right way to test presence-vs-absence of L3. I 4732d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn can't see any guidance on this in the AMD documentation. */ 4747862701c0e3f556e4a0c7ec4074a40526c73a4efflorian size = ((L3i >> 18) & 0x3fff) * 512; 4757862701c0e3f556e4a0c7ec4074a40526c73a4efflorian assoc = decode_AMD_cache_L2_L3_assoc((L3i >> 12) & 0xf); 4767862701c0e3f556e4a0c7ec4074a40526c73a4efflorian line_size = (L3i >> 0) & 0xff; 47738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian ci->caches[3] = VEX_CACHE_INIT(UNIFIED_CACHE, 3, size, line_size, assoc); 4782d853a1f8a153ee1ed99c5e1166d69dd4c6574d8njn } 479b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 480b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote return 0; 481b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote} 482b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 4837862701c0e3f556e4a0c7ec4074a40526c73a4efflorianstatic Int 4847862701c0e3f556e4a0c7ec4074a40526c73a4efflorianget_caches_from_CPUID(VexCacheInfo *ci) 485b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote{ 48694830f470f13df0fcd92bc57bdf312b4716eca31florian Int ret, i; 48794830f470f13df0fcd92bc57bdf312b4716eca31florian UInt level; 48819f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar vendor_id[13]; 489b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 49038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian vg_assert(VG_(has_cpuid)()); 491f4ed059f77bb9788633e02f3151335e64994ebe3tom 49294830f470f13df0fcd92bc57bdf312b4716eca31florian VG_(cpuid)(0, 0, &level, (UInt*)&vendor_id[0], 49394830f470f13df0fcd92bc57bdf312b4716eca31florian (UInt*)&vendor_id[8], (UInt*)&vendor_id[4]); 494b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj vendor_id[12] = '\0'; 495b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 49638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian if (0 == level) { // CPUID level is 0, early Pentium? 497b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote return -1; 498b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote } 499b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 500b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote /* Only handling Intel and AMD chips... no Cyrix, Transmeta, etc */ 501b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote if (0 == VG_(strcmp)(vendor_id, "GenuineIntel")) { 5027862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ret = Intel_cache_info(level, ci); 503b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 504b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote } else if (0 == VG_(strcmp)(vendor_id, "AuthenticAMD")) { 5057862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ret = AMD_cache_info(ci); 506b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 507b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote } else if (0 == VG_(strcmp)(vendor_id, "CentaurHauls")) { 508b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote /* Total kludge. Pretend to be a VIA Nehemiah. */ 5097862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->num_levels = 2; 5107862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->num_caches = 3; 5117862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->icaches_maintain_coherence = True; 5127862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->caches = VG_(malloc)("m_cache", ci->num_caches * sizeof *ci->caches); 5137862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->caches[0] = VEX_CACHE_INIT(DATA_CACHE, 1, 64, 16, 16); 5147862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->caches[1] = VEX_CACHE_INIT(INSN_CACHE, 1, 64, 16, 4); 5157862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->caches[2] = VEX_CACHE_INIT(UNIFIED_CACHE, 2, 64, 16, 16); 5167862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 517b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote ret = 0; 518b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 519b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote } else { 52038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", "CPU vendor ID not recognised (%s)\n", 52138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian vendor_id); 522b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote return -1; 523b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote } 524b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 525b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote /* Successful! Convert sizes from KB to bytes */ 5267862701c0e3f556e4a0c7ec4074a40526c73a4efflorian for (i = 0; i < ci->num_caches; ++i) { 5277862701c0e3f556e4a0c7ec4074a40526c73a4efflorian ci->caches[i].sizeB *= 1024; 528aebbf1c8483de7ef7e5496f96ba4cb868342f439sewardj } 529aebbf1c8483de7ef7e5496f96ba4cb868342f439sewardj 530b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote return ret; 531b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote} 532b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 53338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianstatic Bool 53438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianget_cache_info(VexArchInfo *vai) 5357862701c0e3f556e4a0c7ec4074a40526c73a4efflorian{ 5367862701c0e3f556e4a0c7ec4074a40526c73a4efflorian Int ret = get_caches_from_CPUID(&vai->hwcache_info); 5377862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 5387862701c0e3f556e4a0c7ec4074a40526c73a4efflorian return ret == 0 ? True : False; 5397862701c0e3f556e4a0c7ec4074a40526c73a4efflorian} 5407862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 541cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#elif defined(VGA_arm) || defined(VGA_ppc32) || \ 542cae0cc22b83ffb260ee8379e92099c5a701944cbcarll defined(VGA_ppc64be) || defined(VGA_ppc64le) || \ 543112711afefcfcd43680c7c4aa8d38ef180e8811esewardj defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_arm64) || \ 544112711afefcfcd43680c7c4aa8d38ef180e8811esewardj defined(VGA_tilegx) 54538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianstatic Bool 54638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianget_cache_info(VexArchInfo *vai) 547b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote{ 5487862701c0e3f556e4a0c7ec4074a40526c73a4efflorian vai->hwcache_info.icaches_maintain_coherence = False; 5497862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 5507862701c0e3f556e4a0c7ec4074a40526c73a4efflorian return False; // not yet 551b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote} 552b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote 5537862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#elif defined(VGA_s390x) 5547862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 555fb11d9736384835f3dfe0e627810048c22c5776dflorianstatic ULong 556fb11d9736384835f3dfe0e627810048c22c5776dflorianecag(UInt ai, UInt li, UInt ti) 557fb11d9736384835f3dfe0e627810048c22c5776dflorian{ 558fb11d9736384835f3dfe0e627810048c22c5776dflorian register ULong result asm("2") = 0; 559fb11d9736384835f3dfe0e627810048c22c5776dflorian register ULong input asm("3") = (ai << 4) | (li << 1) | ti; 560fb11d9736384835f3dfe0e627810048c22c5776dflorian 561fb11d9736384835f3dfe0e627810048c22c5776dflorian asm volatile(".short 0xeb20\n\t" 562fb11d9736384835f3dfe0e627810048c22c5776dflorian ".long 0x3000004c\n\t" 563fb11d9736384835f3dfe0e627810048c22c5776dflorian : "=d" (result) : "d" (input)); 564fb11d9736384835f3dfe0e627810048c22c5776dflorian 565fb11d9736384835f3dfe0e627810048c22c5776dflorian return result; 566fb11d9736384835f3dfe0e627810048c22c5776dflorian} 567fb11d9736384835f3dfe0e627810048c22c5776dflorian 568fb11d9736384835f3dfe0e627810048c22c5776dflorianstatic UInt 569fb11d9736384835f3dfe0e627810048c22c5776dflorianget_cache_info_for_level(ULong topology, UInt level) 570fb11d9736384835f3dfe0e627810048c22c5776dflorian{ 571fb11d9736384835f3dfe0e627810048c22c5776dflorian return (topology >> (56 - level * 8)) & 0xff; 572fb11d9736384835f3dfe0e627810048c22c5776dflorian} 573fb11d9736384835f3dfe0e627810048c22c5776dflorian 574fb11d9736384835f3dfe0e627810048c22c5776dflorianstatic ULong 575fb11d9736384835f3dfe0e627810048c22c5776dflorianget_line_size(UInt level, Bool is_insn_cache) 576fb11d9736384835f3dfe0e627810048c22c5776dflorian{ 577fb11d9736384835f3dfe0e627810048c22c5776dflorian return ecag(1, level, is_insn_cache); 578fb11d9736384835f3dfe0e627810048c22c5776dflorian} 579fb11d9736384835f3dfe0e627810048c22c5776dflorian 580fb11d9736384835f3dfe0e627810048c22c5776dflorianstatic ULong 581fb11d9736384835f3dfe0e627810048c22c5776dflorianget_total_size(UInt level, Bool is_insn_cache) 582fb11d9736384835f3dfe0e627810048c22c5776dflorian{ 583fb11d9736384835f3dfe0e627810048c22c5776dflorian return ecag(2, level, is_insn_cache); 584fb11d9736384835f3dfe0e627810048c22c5776dflorian} 585fb11d9736384835f3dfe0e627810048c22c5776dflorian 586fb11d9736384835f3dfe0e627810048c22c5776dflorianstatic ULong 587fb11d9736384835f3dfe0e627810048c22c5776dflorianget_associativity(UInt level, Bool is_insn_cache) 588fb11d9736384835f3dfe0e627810048c22c5776dflorian{ 589fb11d9736384835f3dfe0e627810048c22c5776dflorian return ecag(3, level, is_insn_cache); 590fb11d9736384835f3dfe0e627810048c22c5776dflorian} 591fb11d9736384835f3dfe0e627810048c22c5776dflorian 592fb11d9736384835f3dfe0e627810048c22c5776dflorianstatic VexCache 593fb11d9736384835f3dfe0e627810048c22c5776dflorianget_cache(UInt level, VexCacheKind kind) 594fb11d9736384835f3dfe0e627810048c22c5776dflorian{ 595fb11d9736384835f3dfe0e627810048c22c5776dflorian Bool is_insn_cache = kind == INSN_CACHE; 596fb11d9736384835f3dfe0e627810048c22c5776dflorian UInt size = get_total_size(level, is_insn_cache); 597fb11d9736384835f3dfe0e627810048c22c5776dflorian UInt line_size = get_line_size(level, is_insn_cache); 598fb11d9736384835f3dfe0e627810048c22c5776dflorian UInt assoc = get_associativity(level, is_insn_cache); 599fb11d9736384835f3dfe0e627810048c22c5776dflorian 600fb11d9736384835f3dfe0e627810048c22c5776dflorian return VEX_CACHE_INIT(kind, level + 1, size, line_size, assoc); 601fb11d9736384835f3dfe0e627810048c22c5776dflorian} 602fb11d9736384835f3dfe0e627810048c22c5776dflorian 60338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianstatic Bool 60438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianget_cache_info(VexArchInfo *vai) 6057862701c0e3f556e4a0c7ec4074a40526c73a4efflorian{ 606fb11d9736384835f3dfe0e627810048c22c5776dflorian VexCacheInfo *ci = &vai->hwcache_info; 6077862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 608fb11d9736384835f3dfe0e627810048c22c5776dflorian ci->icaches_maintain_coherence = True; 609fb11d9736384835f3dfe0e627810048c22c5776dflorian 61033332a36b6eba9494a7e8ce7837883379bfb5e53florian if (! (vai->hwcaps & VEX_HWCAPS_S390X_GIE)) { 611fb11d9736384835f3dfe0e627810048c22c5776dflorian // ECAG is not available 612fb11d9736384835f3dfe0e627810048c22c5776dflorian return False; 613fb11d9736384835f3dfe0e627810048c22c5776dflorian } 614fb11d9736384835f3dfe0e627810048c22c5776dflorian 615fb11d9736384835f3dfe0e627810048c22c5776dflorian UInt level, cache_kind, info, i; 616fb11d9736384835f3dfe0e627810048c22c5776dflorian ULong topology = ecag(0, 0, 0); // get summary 617fb11d9736384835f3dfe0e627810048c22c5776dflorian 618fb11d9736384835f3dfe0e627810048c22c5776dflorian /* ECAG supports at most 8 levels of cache. Find out how many levels 619fb11d9736384835f3dfe0e627810048c22c5776dflorian of cache and how many caches there are. */ 620fb11d9736384835f3dfe0e627810048c22c5776dflorian ci->num_levels = 0; 621fb11d9736384835f3dfe0e627810048c22c5776dflorian ci->num_caches = 0; 622fb11d9736384835f3dfe0e627810048c22c5776dflorian for (level = 0; level < 8; level++) { 623fb11d9736384835f3dfe0e627810048c22c5776dflorian info = get_cache_info_for_level(topology, level); 624fb11d9736384835f3dfe0e627810048c22c5776dflorian 625fb11d9736384835f3dfe0e627810048c22c5776dflorian if ((info & 0xc) == 0) break; // cache does not exist at this level 626fb11d9736384835f3dfe0e627810048c22c5776dflorian ++ci->num_levels; 627fb11d9736384835f3dfe0e627810048c22c5776dflorian 628fb11d9736384835f3dfe0e627810048c22c5776dflorian cache_kind = info & 0x3; 629fb11d9736384835f3dfe0e627810048c22c5776dflorian switch (cache_kind) { 630fb11d9736384835f3dfe0e627810048c22c5776dflorian case 0: ci->num_caches += 2; break; /* separate data and insn cache */ 631fb11d9736384835f3dfe0e627810048c22c5776dflorian case 1: ci->num_caches += 1; break; /* only insn cache */ 632fb11d9736384835f3dfe0e627810048c22c5776dflorian case 2: ci->num_caches += 1; break; /* only data cache */ 633fb11d9736384835f3dfe0e627810048c22c5776dflorian case 3: ci->num_caches += 1; break; /* unified data and insn cache */ 634fb11d9736384835f3dfe0e627810048c22c5776dflorian } 635fb11d9736384835f3dfe0e627810048c22c5776dflorian } 636fb11d9736384835f3dfe0e627810048c22c5776dflorian 637fb11d9736384835f3dfe0e627810048c22c5776dflorian ci->caches = VG_(malloc)("m_cache", ci->num_caches * sizeof *ci->caches); 638fb11d9736384835f3dfe0e627810048c22c5776dflorian 639fb11d9736384835f3dfe0e627810048c22c5776dflorian i = 0; 640fb11d9736384835f3dfe0e627810048c22c5776dflorian for (level = 0; level < ci->num_levels; level++) { 641fb11d9736384835f3dfe0e627810048c22c5776dflorian info = get_cache_info_for_level(topology, level); 642fb11d9736384835f3dfe0e627810048c22c5776dflorian cache_kind = info & 0x3; 643fb11d9736384835f3dfe0e627810048c22c5776dflorian switch (cache_kind) { 644fb11d9736384835f3dfe0e627810048c22c5776dflorian case 0: /* separate data and insn cache */ 645fb11d9736384835f3dfe0e627810048c22c5776dflorian ci->caches[i++] = get_cache(level, INSN_CACHE); 646fb11d9736384835f3dfe0e627810048c22c5776dflorian ci->caches[i++] = get_cache(level, DATA_CACHE); 647fb11d9736384835f3dfe0e627810048c22c5776dflorian break; 648fb11d9736384835f3dfe0e627810048c22c5776dflorian 649fb11d9736384835f3dfe0e627810048c22c5776dflorian case 1: /* only insn cache */ 650fb11d9736384835f3dfe0e627810048c22c5776dflorian ci->caches[i++] = get_cache(level, INSN_CACHE); 651fb11d9736384835f3dfe0e627810048c22c5776dflorian break; 652fb11d9736384835f3dfe0e627810048c22c5776dflorian 653fb11d9736384835f3dfe0e627810048c22c5776dflorian case 2: /* only data cache */ 654fb11d9736384835f3dfe0e627810048c22c5776dflorian ci->caches[i++] = get_cache(level, DATA_CACHE); 655fb11d9736384835f3dfe0e627810048c22c5776dflorian break; 656fb11d9736384835f3dfe0e627810048c22c5776dflorian 657fb11d9736384835f3dfe0e627810048c22c5776dflorian case 3: /* unified data and insn cache */ 658fb11d9736384835f3dfe0e627810048c22c5776dflorian ci->caches[i++] = get_cache(level, UNIFIED_CACHE); 659fb11d9736384835f3dfe0e627810048c22c5776dflorian break; 660fb11d9736384835f3dfe0e627810048c22c5776dflorian } 661fb11d9736384835f3dfe0e627810048c22c5776dflorian } 662fb11d9736384835f3dfe0e627810048c22c5776dflorian return True; 6637862701c0e3f556e4a0c7ec4074a40526c73a4efflorian} 6647862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 6657862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#else 6667862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 6677862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#error "Unknown arch" 6687862701c0e3f556e4a0c7ec4074a40526c73a4efflorian 6697862701c0e3f556e4a0c7ec4074a40526c73a4efflorian#endif 6708b68b64759254d514d98328c496cbd88cde4c9a5njn 67138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian/* Debug information */ 67238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianstatic void 67338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianwrite_cache_info(const VexCacheInfo *ci) 67438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian{ 67538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian UInt i; 67638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 67738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", "Cache info:\n"); 67838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", " #levels = %u\n", ci->num_levels); 67938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", " #caches = %u\n", ci->num_caches); 68038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian for (i = 0; i < ci->num_caches; ++i) { 68138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VexCache *c = ci->caches + i; 68238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian const HChar *kind; 68338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", " cache #%u:\n", i); 68438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian switch (c->kind) { 68538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case INSN_CACHE: kind = "insn"; break; 68638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case DATA_CACHE: kind = "data"; break; 68738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case UNIFIED_CACHE: kind = "unified"; break; 68838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian default: kind = "unknown"; break; 68938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 69038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", " kind = %s\n", kind); 69138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", " level = %u\n", c->level); 69238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", " size = %u bytes\n", c->sizeB); 69338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", " linesize = %u bytes\n", c->line_sizeB); 69438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", " assoc = %u\n", c->assoc); 69538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 69638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian} 69738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 69838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianstatic Bool 69938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90floriancache_info_is_sensible(const VexCacheInfo *ci) 70038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian{ 70138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian UInt level, i; 70238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian Bool sensible = True; 70338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 70438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian /* There must be at most one cache of a given kind at the same level. 70538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian If there is a unified cache at a given level, no other cache may 70638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian exist at that level. */ 70738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian for (level = 1; level <= ci->num_levels; ++level) { 70838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian UInt num_icache, num_dcache, num_ucache; 70938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 71038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian num_icache = num_dcache = num_ucache = 0; 71138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian for (i = 0; i < ci->num_caches; ++i) { 71238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian if (ci->caches[i].level == level) { 71338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian switch (ci->caches[i].kind) { 71438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case INSN_CACHE: ++num_icache; break; 71538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case DATA_CACHE: ++num_dcache; break; 71638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian case UNIFIED_CACHE: ++num_ucache; break; 71738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 71838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 71938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 72038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian if (num_icache == 0 && num_dcache == 0 && num_ucache == 0) { 72138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", "warning: No caches at level %u\n", level); 72238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian sensible = False; 72338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 72438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian if (num_icache > 1 || num_dcache > 1 || num_ucache > 1) { 72538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", "warning: More than one cache of a given " 72638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "kind at level %u\n", level); 72738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian sensible = False; 72838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 72938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian if (num_ucache != 0 && (num_icache > 0 || num_dcache > 0)) { 73038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", "warning: Unified cache and I/D cache " 73138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "at level %u\n", level); 73238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian sensible = False; 73338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 73438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 73538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 73638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian /* If there is a cache at level N > 1 there must be a cache at level N-1 */ 73738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian for (level = 2; level <= ci->num_levels; ++level) { 73838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian Bool found = False; 73938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian for (i = 0; i < ci->num_caches; ++i) { 74038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian if (ci->caches[i].level == level - 1) { 74138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian found = True; 74238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian break; 74338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 74438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 74538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian if (! found) { 74638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(debugLog)(1, "cache", "warning: Cache at level %u but no cache " 74738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian "at level %u\n", level, level - 1); 74838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian sensible = False; 74938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 75038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 75138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 75238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian return sensible; 75338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian} 75438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 75538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 75638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian/* Autodetect the cache information for this host and stuff it into 75738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VexArchInfo::hwcache_info. Return True if successful. */ 75838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianBool 75938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florianVG_(machine_get_cache_info)(VexArchInfo *vai) 76038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian{ 76138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian Bool ok = get_cache_info(vai); 76238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 763b7058da8e033c572a5043c66660a98e0c6fec7bbflorian VexCacheInfo *ci = &vai->hwcache_info; 76494830f470f13df0fcd92bc57bdf312b4716eca31florian 76538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian if (! ok) { 766b7058da8e033c572a5043c66660a98e0c6fec7bbflorian VG_(debugLog)(1, "cache", "Could not autodetect cache info\n"); 767b7058da8e033c572a5043c66660a98e0c6fec7bbflorian } else { 768b7058da8e033c572a5043c66660a98e0c6fec7bbflorian ok = cache_info_is_sensible(ci); 76938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 770b7058da8e033c572a5043c66660a98e0c6fec7bbflorian if (! ok) { 771b7058da8e033c572a5043c66660a98e0c6fec7bbflorian VG_(debugLog)(1, "cache", 772b7058da8e033c572a5043c66660a98e0c6fec7bbflorian "Autodetected cache info is not sensible\n"); 773b7058da8e033c572a5043c66660a98e0c6fec7bbflorian } else { 774b7058da8e033c572a5043c66660a98e0c6fec7bbflorian VG_(debugLog)(1, "cache", 775b7058da8e033c572a5043c66660a98e0c6fec7bbflorian "Autodetected cache info is sensible\n"); 776b7058da8e033c572a5043c66660a98e0c6fec7bbflorian } 77738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian write_cache_info(ci); /* write out for debugging */ 778b7058da8e033c572a5043c66660a98e0c6fec7bbflorian } 77938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 780b7058da8e033c572a5043c66660a98e0c6fec7bbflorian if (! ok ) { 78138aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian /* Reset cache info */ 78238aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian ci->num_levels = 0; 78338aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian ci->num_caches = 0; 78438aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian VG_(free)(ci->caches); 78538aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian ci->caches = NULL; 78638aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian } 78738aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 78838aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian return ok; 78938aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian} 79038aeb9ff6ef22dbfd2fe3040c80de932c9a31b90florian 791b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote/*--------------------------------------------------------------------*/ 792b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote/*--- end ---*/ 793b35a8b9024e9bfb4166bc01698710e0af1a0bad9nethercote/*--------------------------------------------------------------------*/ 794