提交 5dd170c6 编写于 作者: T twisti

6812587: Use auxv to determine SPARC hardware features on Solaris

Summary: A similar function to getisax(2) should be used to determine all possible instruction set extensions.
Reviewed-by: never, kvn
上级 00872c6d
/*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -90,7 +90,7 @@ void VM_Version::initialize() {
}
char buf[512];
jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s",
(has_v8() ? ", has_v8" : ""),
(has_v9() ? ", has_v9" : ""),
(has_vis1() ? ", has_vis1" : ""),
......@@ -98,7 +98,9 @@ void VM_Version::initialize() {
(is_ultra3() ? ", is_ultra3" : ""),
(is_sun4v() ? ", is_sun4v" : ""),
(is_niagara1() ? ", is_niagara1" : ""),
(!has_hardware_int_muldiv() ? ", no-muldiv" : ""),
(is_niagara1_plus() ? ", is_niagara1_plus" : ""),
(!has_hardware_mul32() ? ", no-mul32" : ""),
(!has_hardware_div32() ? ", no-div32" : ""),
(!has_hardware_fsmuld() ? ", no-fsmuld" : ""));
// buf is started with ", " or is empty
......
/*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,34 +25,36 @@
class VM_Version: public Abstract_VM_Version {
protected:
enum Feature_Flag {
v8_instructions = 0,
hardware_int_muldiv = 1,
hardware_fsmuld = 2,
v9_instructions = 3,
vis1_instructions = 4,
vis2_instructions = 5,
sun4v_instructions = 6
v8_instructions = 0,
hardware_mul32 = 1,
hardware_div32 = 2,
hardware_fsmuld = 3,
v9_instructions = 4,
vis1_instructions = 5,
vis2_instructions = 6,
sun4v_instructions = 7
};
enum Feature_Flag_Set {
unknown_m = 0,
all_features_m = -1,
v8_instructions_m = 1 << v8_instructions,
hardware_int_muldiv_m = 1 << hardware_int_muldiv,
hardware_fsmuld_m = 1 << hardware_fsmuld,
v9_instructions_m = 1 << v9_instructions,
vis1_instructions_m = 1 << vis1_instructions,
vis2_instructions_m = 1 << vis2_instructions,
sun4v_m = 1 << sun4v_instructions,
generic_v8_m = v8_instructions_m | hardware_int_muldiv_m | hardware_fsmuld_m,
generic_v9_m = generic_v8_m | v9_instructions_m | vis1_instructions_m,
ultra3_m = generic_v9_m | vis2_instructions_m,
unknown_m = 0,
all_features_m = -1,
v8_instructions_m = 1 << v8_instructions,
hardware_mul32_m = 1 << hardware_mul32,
hardware_div32_m = 1 << hardware_div32,
hardware_fsmuld_m = 1 << hardware_fsmuld,
v9_instructions_m = 1 << v9_instructions,
vis1_instructions_m = 1 << vis1_instructions,
vis2_instructions_m = 1 << vis2_instructions,
sun4v_m = 1 << sun4v_instructions,
generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
generic_v9_m = generic_v8_m | v9_instructions_m,
ultra3_m = generic_v9_m | vis1_instructions_m | vis2_instructions_m,
// Temporary until we have something more accurate
niagara1_unique_m = sun4v_m,
niagara1_m = generic_v9_m | niagara1_unique_m
niagara1_unique_m = sun4v_m,
niagara1_m = generic_v9_m | niagara1_unique_m
};
static int _features;
......@@ -62,7 +64,7 @@ protected:
static int determine_features();
static int platform_features(int features);
static bool is_niagara1(int features) { return (features & niagara1_m) == niagara1_m; }
static bool is_niagara1(int features) { return (features & sun4v_m) != 0; }
static int maximum_niagara1_processor_count() { return 32; }
// Returns true if the platform is in the niagara line and
......@@ -76,7 +78,8 @@ public:
// Instruction support
static bool has_v8() { return (_features & v8_instructions_m) != 0; }
static bool has_v9() { return (_features & v9_instructions_m) != 0; }
static bool has_hardware_int_muldiv() { return (_features & hardware_int_muldiv_m) != 0; }
static bool has_hardware_mul32() { return (_features & hardware_mul32_m) != 0; }
static bool has_hardware_div32() { return (_features & hardware_div32_m) != 0; }
static bool has_hardware_fsmuld() { return (_features & hardware_fsmuld_m) != 0; }
static bool has_vis1() { return (_features & vis1_instructions_m) != 0; }
static bool has_vis2() { return (_features & vis2_instructions_m) != 0; }
......
/*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -4451,6 +4451,9 @@ int_fnP_thread_t_i os::Solaris::_thr_setmutator;
int_fnP_thread_t os::Solaris::_thr_suspend_mutator;
int_fnP_thread_t os::Solaris::_thr_continue_mutator;
// (Static) wrapper for getisax(2) call.
os::Solaris::getisax_func_t os::Solaris::_getisax = 0;
// (Static) wrappers for the liblgrp API
os::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home;
os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init;
......@@ -4465,16 +4468,19 @@ os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0;
// (Static) wrapper for meminfo() call.
os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0;
static address resolve_symbol(const char *name) {
address addr;
addr = (address) dlsym(RTLD_DEFAULT, name);
static address resolve_symbol_lazy(const char* name) {
address addr = (address) dlsym(RTLD_DEFAULT, name);
if(addr == NULL) {
// RTLD_DEFAULT was not defined on some early versions of 2.5.1
addr = (address) dlsym(RTLD_NEXT, name);
if(addr == NULL) {
fatal(dlerror());
}
}
return addr;
}
static address resolve_symbol(const char* name) {
address addr = resolve_symbol_lazy(name);
if(addr == NULL) {
fatal(dlerror());
}
return addr;
}
......@@ -4673,15 +4679,26 @@ bool os::Solaris::liblgrp_init() {
}
void os::Solaris::misc_sym_init() {
address func = (address)dlsym(RTLD_DEFAULT, "meminfo");
if(func == NULL) {
func = (address) dlsym(RTLD_NEXT, "meminfo");
address func;
// getisax
func = resolve_symbol_lazy("getisax");
if (func != NULL) {
os::Solaris::_getisax = CAST_TO_FN_PTR(getisax_func_t, func);
}
// meminfo
func = resolve_symbol_lazy("meminfo");
if (func != NULL) {
os::Solaris::set_meminfo(CAST_TO_FN_PTR(meminfo_func_t, func));
}
}
uint_t os::Solaris::getisax(uint32_t* array, uint_t n) {
assert(_getisax != NULL, "_getisax not set");
return _getisax(array, n);
}
// Symbol doesn't exist in Solaris 8 pset.h
#ifndef PS_MYID
#define PS_MYID -3
......@@ -4716,6 +4733,10 @@ void os::init(void) {
Solaris::initialize_system_info();
// Initialize misc. symbols as soon as possible, so we can use them
// if we need them.
Solaris::misc_sym_init();
int fd = open("/dev/zero", O_RDWR);
if (fd < 0) {
fatal1("os::init: cannot open /dev/zero (%s)", strerror(errno));
......@@ -4857,7 +4878,6 @@ jint os::init_2(void) {
}
}
Solaris::misc_sym_init();
Solaris::signal_sets_init();
Solaris::init_signal_mem();
Solaris::install_signal_handlers();
......
/*
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -72,6 +72,8 @@ class Solaris {
LGRP_VIEW_OS /* what's available to operating system */
} lgrp_view_t;
typedef uint_t (*getisax_func_t)(uint32_t* array, uint_t n);
typedef lgrp_id_t (*lgrp_home_func_t)(idtype_t idtype, id_t id);
typedef lgrp_cookie_t (*lgrp_init_func_t)(lgrp_view_t view);
typedef int (*lgrp_fini_func_t)(lgrp_cookie_t cookie);
......@@ -87,6 +89,8 @@ class Solaris {
const uint_t info_req[], int info_count,
uint64_t outdata[], uint_t validity[]);
static getisax_func_t _getisax;
static lgrp_home_func_t _lgrp_home;
static lgrp_init_func_t _lgrp_init;
static lgrp_fini_func_t _lgrp_fini;
......@@ -283,6 +287,9 @@ class Solaris {
}
static lgrp_cookie_t lgrp_cookie() { return _lgrp_cookie; }
static bool supports_getisax() { return _getisax != NULL; }
static uint_t getisax(uint32_t* array, uint_t n);
static void set_meminfo(meminfo_func_t func) { _meminfo = func; }
static int meminfo (const uint64_t inaddr[], int addr_count,
const uint_t info_req[], int info_count,
......
/*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2006-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,58 +25,106 @@
# include "incls/_precompiled.incl"
# include "incls/_vm_version_solaris_sparc.cpp.incl"
# include <sys/auxv.h>
# include <sys/auxv_SPARC.h>
# include <sys/systeminfo.h>
int VM_Version::platform_features(int features) {
// We determine what sort of hardware we have via sysinfo(SI_ISALIST, ...).
// This isn't the best of all possible ways because there's not enough
// detail in the isa list it returns, but it's a bit less arcane than
// generating assembly code and an illegal instruction handler. We used
// to generate a getpsr trap, but that's even more arcane.
//
// Another possibility would be to use sysinfo(SI_PLATFORM, ...), but
// that would require more knowledge here than is wise.
// We need to keep these here as long as we have to build on Solaris
// versions before 10.
#ifndef SI_ARCHITECTURE_32
#define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */
#endif
// isalist spec via 'man isalist' as of 01-Aug-2001
#ifndef SI_ARCHITECTURE_64
#define SI_ARCHITECTURE_64 517 /* basic 64-bit SI_ARCHITECTURE */
#endif
static void do_sysinfo(int si, const char* string, int* features, int mask) {
char tmp;
size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1);
char* buf = (char*)malloc(bufsize);
if (buf != NULL) {
if (sysinfo(SI_ISALIST, buf, bufsize) == bufsize) {
// Figure out what kind of sparc we have
char *sparc_string = strstr(buf, "sparc");
if (sparc_string != NULL) { features |= v8_instructions_m;
if (sparc_string[5] == 'v') {
if (sparc_string[6] == '8') {
if (sparc_string[7] == '-') features |= hardware_int_muldiv_m;
else if (sparc_string[7] == 'p') features |= generic_v9_m;
else features |= generic_v8_m;
} else if (sparc_string[6] == '9') features |= generic_v9_m;
}
}
size_t bufsize = sysinfo(si, &tmp, 1);
// Check for visualization instructions
char *vis = strstr(buf, "vis");
if (vis != NULL) { features |= vis1_instructions_m;
if (vis[3] == '2') features |= vis2_instructions_m;
}
// All SI defines used below must be supported.
guarantee(bufsize != -1, "must be supported");
char* buf = (char*) malloc(bufsize);
if (buf == NULL)
return;
if (sysinfo(si, buf, bufsize) == bufsize) {
// Compare the string.
if (strcmp(buf, string) == 0) {
*features |= mask;
}
free(buf);
}
bufsize = sysinfo(SI_MACHINE, &tmp, 1);
buf = (char*)malloc(bufsize);
free(buf);
}
int VM_Version::platform_features(int features) {
// getisax(2), SI_ARCHITECTURE_32, and SI_ARCHITECTURE_64 are
// supported on Solaris 10 and later.
if (os::Solaris::supports_getisax()) {
#ifndef PRODUCT
if (PrintMiscellaneous && Verbose)
tty->print_cr("getisax(2) supported.");
#endif
if (buf != NULL) {
if (sysinfo(SI_MACHINE, buf, bufsize) == bufsize) {
if (strstr(buf, "sun4v") != NULL) {
features |= sun4v_m;
// Check 32-bit architecture.
do_sysinfo(SI_ARCHITECTURE_32, "sparc", &features, v8_instructions_m);
// Check 64-bit architecture.
do_sysinfo(SI_ARCHITECTURE_64, "sparcv9", &features, generic_v9_m);
// Extract valid instruction set extensions.
uint_t av;
uint_t avn = os::Solaris::getisax(&av, 1);
assert(avn == 1, "should only return one av");
if (av & AV_SPARC_MUL32) features |= hardware_mul32_m;
if (av & AV_SPARC_DIV32) features |= hardware_div32_m;
if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m;
if (av & AV_SPARC_V8PLUS) features |= v9_instructions_m;
if (av & AV_SPARC_VIS) features |= vis1_instructions_m;
if (av & AV_SPARC_VIS2) features |= vis2_instructions_m;
} else {
// getisax(2) failed, use the old legacy code.
#ifndef PRODUCT
if (PrintMiscellaneous && Verbose)
tty->print_cr("getisax(2) not supported.");
#endif
char tmp;
size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1);
char* buf = (char*) malloc(bufsize);
if (buf != NULL) {
if (sysinfo(SI_ISALIST, buf, bufsize) == bufsize) {
// Figure out what kind of sparc we have
char *sparc_string = strstr(buf, "sparc");
if (sparc_string != NULL) { features |= v8_instructions_m;
if (sparc_string[5] == 'v') {
if (sparc_string[6] == '8') {
if (sparc_string[7] == '-') { features |= hardware_mul32_m;
features |= hardware_div32_m;
} else if (sparc_string[7] == 'p') features |= generic_v9_m;
else features |= generic_v8_m;
} else if (sparc_string[6] == '9') features |= generic_v9_m;
}
}
// Check for visualization instructions
char *vis = strstr(buf, "vis");
if (vis != NULL) { features |= vis1_instructions_m;
if (vis[3] == '2') features |= vis2_instructions_m;
}
}
free(buf);
}
free(buf);
}
// Determine the machine type.
do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m);
return features;
}
......@@ -4598,6 +4598,7 @@ vm_version_<arch>.cpp vm_version_<arch>.hpp
vm_version_<arch>.hpp globals_extension.hpp
vm_version_<arch>.hpp vm_version.hpp
vm_version_<os_arch>.cpp os.hpp
vm_version_<os_arch>.cpp vm_version_<arch>.hpp
vmreg.cpp assembler.hpp
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册