aboutsummaryrefslogtreecommitdiffstats
path: root/java/org/tinyb/PlatformToolkit.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/org/tinyb/PlatformToolkit.java')
-rw-r--r--java/org/tinyb/PlatformToolkit.java255
1 files changed, 250 insertions, 5 deletions
diff --git a/java/org/tinyb/PlatformToolkit.java b/java/org/tinyb/PlatformToolkit.java
index 99f9f0e7..5e807ab1 100644
--- a/java/org/tinyb/PlatformToolkit.java
+++ b/java/org/tinyb/PlatformToolkit.java
@@ -25,6 +25,10 @@
package org.tinyb;
import java.io.File;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
@@ -39,6 +43,194 @@ final class PlatformToolkit {
public enum OSType {
UNIX, MACOS, IOS, WINDOWS;
}
+ public enum CPUFamily {
+ /** AMD/Intel */
+ X86,
+ /** ARM 32bit */
+ ARM32,
+ /** ARM 64bit */
+ ARM64,
+ /** Power PC */
+ PPC,
+ /** SPARC */
+ SPARC,
+ /** Mips */
+ MIPS,
+ /** PA RISC */
+ PA_RISC,
+ /** Itanium */
+ IA64,
+ /** Hitachi SuperH */
+ SuperH;
+ }
+ public enum CPUType {
+ /** ARM 32bit default, usually little endian */
+ ARM( CPUFamily.ARM32, true),
+ /** ARM7EJ, ARM9E, ARM10E, XScale, usually little endian */
+ ARMv5( CPUFamily.ARM32, true),
+ /** ARM11, usually little endian */
+ ARMv6( CPUFamily.ARM32, true),
+ /** ARM Cortex, usually little endian */
+ ARMv7( CPUFamily.ARM32, true),
+ // 4
+
+ /** X86 32bit, little endian */
+ X86_32( CPUFamily.X86, true),
+ /** PPC 32bit default, usually big endian */
+ PPC( CPUFamily.PPC, true),
+ /** MIPS 32bit, big endian (mips) or little endian (mipsel) */
+ MIPS_32( CPUFamily.MIPS, true),
+ /** Hitachi SuperH 32bit default, ??? endian */
+ SuperH( CPUFamily.SuperH, true),
+ /** SPARC 32bit, big endian */
+ SPARC_32( CPUFamily.SPARC, true),
+ // 9
+
+ /** ARM64 default (64bit), usually little endian */
+ ARM64( CPUFamily.ARM64, false),
+ /** ARM AArch64 (64bit), usually little endian */
+ ARMv8_A( CPUFamily.ARM64, false),
+ /** X86 64bit, little endian */
+ X86_64( CPUFamily.X86, false),
+ /** PPC 64bit default, usually big endian */
+ PPC64( CPUFamily.PPC, false),
+ /** MIPS 64bit, big endian (mips64) or little endian (mipsel64) ? */
+ MIPS_64( CPUFamily.MIPS, false),
+ /** Itanium 64bit default, little endian */
+ IA64( CPUFamily.IA64, false),
+ /** SPARC 64bit, big endian */
+ SPARCV9_64(CPUFamily.SPARC, false),
+ /** PA_RISC2_0 64bit, ??? endian */
+ PA_RISC2_0(CPUFamily.PA_RISC, false);
+ // 17
+
+ public final CPUFamily family;
+ public final boolean is32Bit;
+
+ CPUType(final CPUFamily type, final boolean is32Bit){
+ this.family = type;
+ this.is32Bit = is32Bit;
+ }
+
+ /**
+ * Returns {@code true} if the given {@link CPUType} is compatible
+ * w/ this one, i.e. at least {@link #family} and {@link #is32Bit} is equal.
+ */
+ public final boolean isCompatible(final CPUType other) {
+ if( null == other ) {
+ return false;
+ } else if( other == this ) {
+ return true;
+ } else {
+ return this.family == other.family &&
+ this.is32Bit == other.is32Bit;
+ }
+ }
+
+ public static final CPUType query(final String cpuABILower) {
+ if( null == cpuABILower ) {
+ throw new IllegalArgumentException("Null cpuABILower arg");
+ }
+ if( cpuABILower.equals("x86") ||
+ cpuABILower.equals("i386") ||
+ cpuABILower.equals("i486") ||
+ cpuABILower.equals("i586") ||
+ cpuABILower.equals("i686") ) {
+ return X86_32;
+ } else if( cpuABILower.equals("x86_64") ||
+ cpuABILower.equals("amd64") ) {
+ return X86_64;
+ } else if( cpuABILower.equals("ia64") ) {
+ return IA64;
+ } else if( cpuABILower.equals("aarch64") ) {
+ return ARM64;
+ } else if( cpuABILower.startsWith("arm") ) {
+ if( cpuABILower.equals("armv8-a") ||
+ cpuABILower.equals("arm-v8-a") ||
+ cpuABILower.equals("arm-8-a") ||
+ cpuABILower.equals("arm64-v8a") ) {
+ return ARMv8_A;
+ } else if( cpuABILower.startsWith("arm64") ) {
+ return ARM64;
+ } else if( cpuABILower.startsWith("armv7") ||
+ cpuABILower.startsWith("arm-v7") ||
+ cpuABILower.startsWith("arm-7") ||
+ cpuABILower.startsWith("armeabi-v7") ) {
+ return ARMv7;
+ } else if( cpuABILower.startsWith("armv5") ||
+ cpuABILower.startsWith("arm-v5") ||
+ cpuABILower.startsWith("arm-5") ) {
+ return ARMv5;
+ } else if( cpuABILower.startsWith("armv6") ||
+ cpuABILower.startsWith("arm-v6") ||
+ cpuABILower.startsWith("arm-6") ) {
+ return ARMv6;
+ } else {
+ return ARM;
+ }
+ } else if( cpuABILower.equals("sparcv9") ) {
+ return SPARCV9_64;
+ } else if( cpuABILower.equals("sparc") ) {
+ return SPARC_32;
+ } else if( cpuABILower.equals("pa_risc2.0") ) {
+ return PA_RISC2_0;
+ } else if( cpuABILower.startsWith("ppc64") ) {
+ return PPC64;
+ } else if( cpuABILower.startsWith("ppc") ) {
+ return PPC;
+ } else if( cpuABILower.startsWith("mips64") ) {
+ return MIPS_64;
+ } else if( cpuABILower.startsWith("mips") ) {
+ return MIPS_32;
+ } else if( cpuABILower.startsWith("superh") ) {
+ return SuperH;
+ } else {
+ throw new RuntimeException("Please port CPUType detection to your platform (CPU_ABI string '" + cpuABILower + "')");
+ }
+ }
+ }
+ public enum ABIType {
+ GENERIC_ABI ( 0x00 ),
+ /** ARM GNU-EABI ARMEL -mfloat-abi=softfp */
+ EABI_GNU_ARMEL ( 0x01 ),
+ /** ARM GNU-EABI ARMHF -mfloat-abi=hard */
+ EABI_GNU_ARMHF ( 0x02 ),
+ /** ARM EABI AARCH64 (64bit) */
+ EABI_AARCH64 ( 0x03 );
+
+ public final int id;
+
+ ABIType(final int id){
+ this.id = id;
+ }
+
+ /**
+ * Returns {@code true} if the given {@link ABIType} is compatible
+ * w/ this one, i.e. they are equal.
+ */
+ public final boolean isCompatible(final ABIType other) {
+ if( null == other ) {
+ return false;
+ } else {
+ return other == this;
+ }
+ }
+
+ public static final ABIType query(final CPUType cpuType, final String cpuABILower) {
+ if( null == cpuType ) {
+ throw new IllegalArgumentException("Null cpuType");
+ } else if( null == cpuABILower ) {
+ throw new IllegalArgumentException("Null cpuABILower");
+ } else if( CPUFamily.ARM64 == cpuType.family ) {
+ return EABI_AARCH64;
+ } else if( CPUFamily.ARM32 == cpuType.family ) {
+ // FIXME: We only support EABI_GNU_ARMHF on ARM 32bit for now!
+ return EABI_GNU_ARMHF;
+ } else {
+ return GENERIC_ABI;
+ }
+ }
+ }
/** Lower case system property '{@code os.name}'. */
static final String os_name;
@@ -76,16 +268,21 @@ final class PlatformToolkit {
});
int i=0;
os_name = props[i++];
- os_arch = props[i++];
+ final String _os_arch1 = props[i++];
user_dir = props[i++];
java_user_lib_path = props[i++];
java_boot_lib_path = props[i++];
- }
- if( null != os_name && os_name.length() > 0 && null != os_arch && os_arch.length() > 0 ) {
+ final boolean LITTLE_ENDIAN = queryIsLittleEndianImpl();
+ final CPUType CPU_TYPE = CPUType.query(_os_arch1);
+ final ABIType ABI_TYPE = ABIType.query(CPU_TYPE, _os_arch1);
+ final String _os_arch2 = getArchName(CPU_TYPE, ABI_TYPE, LITTLE_ENDIAN);
+ os_arch = null != _os_arch2 ? _os_arch2 : _os_arch1;
os_and_arch = os_name+"-"+os_arch;
- } else {
- os_and_arch = null;
+ if( BluetoothFactory.DEBUG ) {
+ System.err.println("PlatformToolkit: os_name "+os_name+", os_arch ("+_os_arch1+" -> "+_os_arch2+" ->) "+os_arch+" (final), "+
+ "CPU_TYPE "+CPU_TYPE+", ABI_TYPE "+ABI_TYPE+", LITTLE_ENDIAN "+LITTLE_ENDIAN);
+ }
}
if ( os_name.startsWith("mac os x") ||
@@ -123,6 +320,54 @@ final class PlatformToolkit {
}
}
+ private static final boolean queryIsLittleEndianImpl() {
+ final ByteBuffer tst_b = ByteBuffer.allocateDirect(4 /* SIZEOF_INT */).order(ByteOrder.nativeOrder()); // 32bit in native order
+ final IntBuffer tst_i = tst_b.asIntBuffer();
+ final ShortBuffer tst_s = tst_b.asShortBuffer();
+ tst_i.put(0, 0x0A0B0C0D);
+ return 0x0C0D == tst_s.get(0);
+ }
+ private static final String getArchName(final CPUType cpuType, final ABIType abiType, final boolean littleEndian) {
+ switch( abiType ) {
+ case EABI_GNU_ARMEL:
+ return "arm"; // actually not supported!
+ case EABI_GNU_ARMHF:
+ return "armhf";
+ case EABI_AARCH64:
+ return "aarch64";
+ default:
+ break;
+ }
+
+ switch( cpuType ) {
+ case X86_32:
+ return "i386";
+ case PPC:
+ return "ppc";
+ case MIPS_32:
+ return littleEndian ? "mipsel" : "mips";
+ case SuperH:
+ return "superh";
+ case SPARC_32:
+ return "sparc";
+
+ case X86_64:
+ return "amd64";
+ case PPC64:
+ return littleEndian ? "ppc64le" : "ppc64";
+ case MIPS_64:
+ return "mips64";
+ case IA64:
+ return "ia64";
+ case SPARCV9_64:
+ return "sparcv9";
+ case PA_RISC2_0:
+ return "risc2.0";
+ default:
+ return null;
+ }
+ }
+
/**
* Produces a list of potential full native library pathnames, denoted by its {@code libBaseName}.
*