diff options
Diffstat (limited to 'java/org/tinyb/PlatformToolkit.java')
-rw-r--r-- | java/org/tinyb/PlatformToolkit.java | 255 |
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}. * |