11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "memory/allocation.hpp" 27 #include "memory/allocation.inline.hpp" 28 #include "runtime/os.hpp" 29 #include "vm_version_sparc.hpp" 30 31 # include <sys/auxv.h> 32 # include <sys/auxv_SPARC.h> 33 # include <sys/systeminfo.h> 34 # include <kstat.h> 35 36 // We need to keep these here as long as we have to build on Solaris 37 // versions before 10. 38 #ifndef SI_ARCHITECTURE_32 39 #define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */ 40 #endif 41 42 #ifndef SI_ARCHITECTURE_64 43 #define SI_ARCHITECTURE_64 517 /* basic 64-bit SI_ARCHITECTURE */ 44 #endif 45 46 static void do_sysinfo(int si, const char* string, int* features, int mask) { 47 char tmp; 48 size_t bufsize = sysinfo(si, &tmp, 1); 49 50 // All SI defines used below must be supported. 51 guarantee(bufsize != -1, "must be supported"); 52 53 char* buf = (char*) os::malloc(bufsize, mtInternal); 54 194 // kstat on Solaris 8 virtual machines (branded zones) 195 // returns "(unsupported)" implementation. Solaris 8 is not 196 // supported anymore, but include this check to be on the 197 // safe side. 198 warning("kstat cpu_info implementation = '%s', assume generic SPARC", impl); 199 #endif 200 implementation = "SPARC"; 201 } 202 } 203 os::free((void*)impl); 204 break; 205 } 206 } // for( 207 } 208 } 209 assert(strcmp(implementation, "UNKNOWN") != 0, 210 "unknown cpu info (changed kstat interface?)"); 211 kstat_close(kc); 212 } 213 214 return features; 215 } | 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "memory/allocation.hpp" 27 #include "memory/allocation.inline.hpp" 28 #include "runtime/os.hpp" 29 #include "vm_version_sparc.hpp" 30 31 #include <sys/auxv.h> 32 #include <sys/auxv_SPARC.h> 33 #include <sys/systeminfo.h> 34 #include <kstat.h> 35 #include <picl.h> 36 37 extern "C" static int PICL_cpu_visitor_helper(picl_nodehdl_t nodeh, void *result); 38 39 class PICL { 40 // Get a value of the integer property. The value in the tree can be either 32 or 64 bit 41 // depending on the platform. The result is converted to int. 42 static int get_int_property(picl_nodehdl_t nodeh, const char* name, int* result) { 43 picl_propinfo_t pinfo; 44 picl_prophdl_t proph; 45 if (picl_get_prop_by_name(nodeh, name, &proph) != PICL_SUCCESS || 46 picl_get_propinfo(proph, &pinfo) != PICL_SUCCESS) { 47 return PICL_FAILURE; 48 } 49 50 if (pinfo.type != PICL_PTYPE_INT) { 51 assert(false, "Invalid property type"); 52 return PICL_FAILURE; 53 } 54 if (pinfo.size == sizeof(int64_t)) { 55 int64_t val; 56 if (picl_get_propval(proph, &val, sizeof(int64_t)) != PICL_SUCCESS) { 57 return PICL_FAILURE; 58 } 59 *result = static_cast<int>(val); 60 } else if (pinfo.size == sizeof(int32_t)) { 61 int32_t val; 62 if (picl_get_propval(proph, &val, sizeof(int32_t)) != PICL_SUCCESS) { 63 return PICL_FAILURE; 64 } 65 *result = static_cast<int>(val); 66 } else { 67 assert(false, "Unexpected integer property size"); 68 return PICL_FAILURE; 69 } 70 return PICL_SUCCESS; 71 } 72 73 // For every visited node make sure the specified property exists and has the same value 74 static int get_int_property_and_ensure_consistency(picl_nodehdl_t nodeh, const char* name, void *result) { 75 int *prev = static_cast<int*>(result); 76 int curr; 77 if (*prev >= 0) { // are still interested in walking? 78 if (get_int_property(nodeh, name, &curr) == PICL_SUCCESS) { 79 if (*prev == 0) { // first 80 *prev = curr; 81 return PICL_WALK_CONTINUE; 82 } else if (curr == *prev) { // others 83 return PICL_WALK_CONTINUE; 84 } 85 } 86 *prev = -1; 87 } 88 return PICL_WALK_TERMINATE; 89 } 90 91 int _L1_data_cache_line_size; 92 int _L2_cache_line_size; 93 94 public: 95 static int cpu_visitor(picl_nodehdl_t nodeh, void *result) 96 { 97 PICL *picl = static_cast<PICL*>(result); 98 int r1 = get_int_property_and_ensure_consistency(nodeh, "l2-cache-line-size", &(picl->_L2_cache_line_size)); 99 int r2 = get_int_property_and_ensure_consistency(nodeh, "l1-dcache-line-size", &(picl->_L1_data_cache_line_size)); 100 if (r1 == PICL_WALK_TERMINATE && r2 == PICL_WALK_TERMINATE) { 101 return PICL_WALK_TERMINATE; 102 } 103 return PICL_WALK_CONTINUE; 104 } 105 106 PICL() : _L1_data_cache_line_size(0), _L2_cache_line_size(0) { 107 if (picl_initialize() == PICL_SUCCESS) { 108 picl_nodehdl_t rooth; 109 if (picl_get_root(&rooth) == PICL_SUCCESS) { 110 // Visit all CPUs 111 picl_walk_tree_by_class(rooth, "cpu", this, PICL_cpu_visitor_helper); 112 } 113 picl_shutdown(); 114 } 115 } 116 117 unsigned int L1_data_cache_line_size() const { return MAX2(0, _L1_data_cache_line_size); } 118 unsigned int L2_cache_line_size() const { return MAX2(0, _L2_cache_line_size); } 119 }; 120 121 extern "C" static int PICL_cpu_visitor_helper(picl_nodehdl_t nodeh, void *result) { 122 return PICL::cpu_visitor(nodeh, result); 123 } 124 125 // We need to keep these here as long as we have to build on Solaris 126 // versions before 10. 127 #ifndef SI_ARCHITECTURE_32 128 #define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */ 129 #endif 130 131 #ifndef SI_ARCHITECTURE_64 132 #define SI_ARCHITECTURE_64 517 /* basic 64-bit SI_ARCHITECTURE */ 133 #endif 134 135 static void do_sysinfo(int si, const char* string, int* features, int mask) { 136 char tmp; 137 size_t bufsize = sysinfo(si, &tmp, 1); 138 139 // All SI defines used below must be supported. 140 guarantee(bufsize != -1, "must be supported"); 141 142 char* buf = (char*) os::malloc(bufsize, mtInternal); 143 283 // kstat on Solaris 8 virtual machines (branded zones) 284 // returns "(unsupported)" implementation. Solaris 8 is not 285 // supported anymore, but include this check to be on the 286 // safe side. 287 warning("kstat cpu_info implementation = '%s', assume generic SPARC", impl); 288 #endif 289 implementation = "SPARC"; 290 } 291 } 292 os::free((void*)impl); 293 break; 294 } 295 } // for( 296 } 297 } 298 assert(strcmp(implementation, "UNKNOWN") != 0, 299 "unknown cpu info (changed kstat interface?)"); 300 kstat_close(kc); 301 } 302 303 // Figure out cache line sizes using PICL 304 PICL picl; 305 _L1_data_cache_line_size = picl.L1_data_cache_line_size(); 306 _L2_cache_line_size = picl.L2_cache_line_size(); 307 308 return features; 309 } |