1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2009, Intel Corporation. 24 * All rights reserved. 25 */ 26 27 /* 28 * Portions Copyright 2009 Advanced Micro Devices, Inc. 29 */ 30 31 #include <sys/types.h> 32 #include "proc64_id.h" 33 34 /* 35 * Intel cpuid eax=4 Cache Types 36 */ 37 #define NULL_CACHE 0x0 38 #define DATA_CACHE 0x1 39 #define INSTRUCTION_CACHE 0x2 40 #define UNIFIED_CACHE 0x3 41 42 struct cpuid_values { 43 uint_t eax; 44 uint_t ebx; 45 uint_t ecx; 46 uint_t edx; 47 }; 48 49 /* 50 * get_intel_cache_info() 51 * Get cpu cache sizes for optimized 64-bit libc functions mem* and str*. 52 * Find the sizes of the 1st, 2nd and largest level caches. 53 */ 54 static void 55 get_intel_cache_info(void) 56 { 57 int cache_level; 58 int largest_cache_level = 0; 59 int cache_index = 0; 60 int cache_type; 61 int line_size, partitions, ways, sets; 62 uint_t cache_size; 63 uint_t l1_cache_size = 0; 64 uint_t l2_cache_size = 0; 65 uint_t largest_level_cache = 0; 66 struct cpuid_values cpuid_info; 67 68 while (1) { 69 __libc_get_cpuid(4, (uint_t *)&cpuid_info, cache_index); 70 71 cache_type = cpuid_info.eax & 0x1f; 72 if (cache_type == NULL_CACHE) { 73 /* 74 * No more caches. 75 */ 76 break; 77 } 78 cache_index += 1; 79 80 if (cache_type == INSTRUCTION_CACHE) { 81 /* 82 * Don't care for memops 83 */ 84 continue; 85 } 86 87 cache_level = (cpuid_info.eax >> 0x5) & 0x7; 88 line_size = (cpuid_info.ebx & 0xfff) + 1; 89 partitions = ((cpuid_info.ebx >> 12) & 0x3ff) + 1; 90 ways = ((cpuid_info.ebx >> 22) & 0x3ff) + 1; 91 sets = cpuid_info.ecx + 1; 92 cache_size = ways * partitions * line_size * sets; 93 94 if (cache_level == 1) { 95 l1_cache_size = cache_size; 96 } 97 if (cache_level == 2) { 98 l2_cache_size = cache_size; 99 } 100 if (cache_level > largest_cache_level) { 101 largest_cache_level = cache_level; 102 largest_level_cache = cache_size; 103 } 104 } 105 106 __set_cache_sizes(l1_cache_size, l2_cache_size, largest_level_cache); 107 } 108 109 /* 110 * get_amd_cache_info() 111 * Same as get_intel_cache_info() but for AMD processors 112 */ 113 static void 114 get_amd_cache_info(void) 115 { 116 uint_t l1_cache_size = AMD_DFLT_L1_CACHE_SIZE; 117 uint_t l2_cache_size = AMD_DFLT_L2_CACHE_SIZE; 118 uint_t l3_cache_size = 0; 119 uint_t largest_level_cache = 0; 120 struct cpuid_values cpuid_info; 121 uint_t maxeax; 122 int ncores; 123 124 cpuid_info.eax = 0; 125 __libc_get_cpuid(0x80000000, (uint_t *)&cpuid_info, -1); 126 maxeax = cpuid_info.eax; 127 128 if (maxeax >= 0x80000005) { /* We have L1D info */ 129 __libc_get_cpuid(0x80000005, (uint_t *)&cpuid_info, -1); 130 l1_cache_size = ((cpuid_info.ecx >> 24) & 0xff) * 1024; 131 } 132 133 if (maxeax >= 0x80000006) { /* We have L2 and L3 info */ 134 __libc_get_cpuid(0x80000006, (uint_t *)&cpuid_info, -1); 135 l2_cache_size = ((cpuid_info.ecx >> 16) & 0xffff) * 1024; 136 l3_cache_size = ((cpuid_info.edx >> 18) & 0x3fff) * 512 * 1024; 137 } 138 139 /* 140 * L3 cache is shared between cores on the processor 141 */ 142 if (maxeax >= 0x80000008 && l3_cache_size != 0) { 143 largest_level_cache = l3_cache_size; 144 145 /* 146 * Divide by number of cores on the processor 147 */ 148 __libc_get_cpuid(0x80000008, (uint_t *)&cpuid_info, -1); 149 ncores = (cpuid_info.ecx & 0xff) + 1; 150 if (ncores > 1) 151 largest_level_cache /= ncores; 152 153 /* 154 * L3 is a victim cache for L2 155 */ 156 largest_level_cache += l2_cache_size; 157 } else { 158 largest_level_cache = l2_cache_size; 159 } 160 161 __set_cache_sizes(l1_cache_size, l2_cache_size, 162 largest_level_cache); 163 } 164 165 /* 166 * proc64_id() 167 * Determine cache and SSE level to use for memops and strops specific to 168 * processor type. 169 */ 170 void 171 __proc64id(void) 172 { 173 int use_sse = NO_SSE; 174 struct cpuid_values cpuid_info; 175 176 __libc_get_cpuid(0, &cpuid_info, 0); 177 178 /* 179 * Check for AuthenticAMD 180 */ 181 if ((cpuid_info.ebx == 0x68747541) && /* Auth */ 182 (cpuid_info.edx == 0x69746e65) && /* enti */ 183 (cpuid_info.ecx == 0x444d4163)) { /* cAMD */ 184 get_amd_cache_info(); 185 return; 186 } 187 188 /* 189 * Check for GenuineIntel 190 */ 191 if ((cpuid_info.ebx != 0x756e6547) || /* Genu */ 192 (cpuid_info.edx != 0x49656e69) || /* ineI */ 193 (cpuid_info.ecx != 0x6c65746e)) { /* ntel */ 194 /* 195 * Not Intel - use defaults. 196 */ 197 return; 198 } 199 200 /* 201 * Genuine Intel 202 */ 203 204 /* 205 * Look for CPUID function 4 support - Deterministic Cache Parameters. 206 * Otherwise use default cache sizes. 207 */ 208 if (cpuid_info.eax >= 4) { 209 get_intel_cache_info(); 210 211 /* 212 * Check what SSE versions are supported. 213 */ 214 __libc_get_cpuid(1, &cpuid_info, 0); 215 if (cpuid_info.ecx & CPUID_INTC_ECX_SSE4_2) { 216 use_sse |= USE_SSE4_2; 217 } 218 if (cpuid_info.ecx & CPUID_INTC_ECX_SSE4_1) { 219 use_sse |= USE_SSE4_1; 220 } 221 if (cpuid_info.ecx & CPUID_INTC_ECX_SSSE3) { 222 use_sse |= USE_SSSE3; 223 } 224 if (cpuid_info.ecx & CPUID_INTC_ECX_SSE3) { 225 use_sse |= USE_SSE3; 226 } 227 if (cpuid_info.edx & CPUID_INTC_EDX_SSE2) { 228 use_sse |= USE_SSE2; 229 } 230 use_sse |= USE_BSF; 231 __intel_set_memops_method(use_sse); 232 } else { 233 __set_cache_sizes(INTEL_DFLT_L1_CACHE_SIZE, 234 INTEL_DFLT_L2_CACHE_SIZE, 235 INTEL_DFLT_LARGEST_CACHE_SIZE); 236 __intel_set_memops_method(use_sse); 237 } 238 } 239