Folks, I've taken the liberty of inviting myself to the party :) I'm also on IRC on Freenode, and have been following RPM development for some time in a lurking capacity. A number of you know me from the office, but greetings to everyone else!
We're currently engaged in bootstrapping support for "hardfp"[0] in the Fedora Linux distribution (specifically, in release 15 thereof) for use by systems featuring an ARM version 7 A (Application) processor or later ARM. This is a new ABI as far as Linux is concerned, and it is parallel installable with the older "EABI" or (loosely) "softfp" that has been supported up until this point (for example in our ARM version 5 port, as released in Fedora 13). Currently, we have a hacked up RPM binary that introduces e.g.: * armv7hl * armv7nhl (MeeGo disagrees on this and calls it "hnl" btw) * armv7thl [1] Dennis has some code (he can forward) that is carried in F15 currently, and which Panu has previously taken a look at. It uses the typical parsing of /proc as an approach, though we agree that the "correct" way to do that would be through AT_HWCAPS, as in here: https://wiki.linaro.org/Resources/HowTo/DeterminingCPUFeatures (last raised on rpm-maint@ in 2008 as it turns out :) ) All of the existing stuff assumes that if we have vfpv3 on ARMv7 we're going to be running in hardfp. We can keep that notion around in the very short term, but we need a longer term solution. And although we don't necessarily plan actual parallel installs of different ABIs, it is not technically the case that all ARMv7 systems are going to be running the hardfp port. We may e.g. install an ARMv5 port therein. Add to this the fact that we now have X32 (a new x86 32-bit ABI) in the Intel world, and it's clear that RPM needs a generic way to handle multiple possible ABIs within the same architecture. I personally favor the "multiarch" approach being taken by Debian, but I don't really want to espouse one particular approach here. What I do want to do is to kick off a discussion thread in which you RPM folks can decide how you want to handle multiple ABIs in both the ARM and non-ARM worlds that myself, Dennis, and others occupy. I'm sure Dennis, Panu, and others can point folks at existing patches. What I want out of this discussion is a decision around how multiple ABIs within an architecture will be handled in general. If you're allergic to ARM, consider that in the Intel space there is now IA32, X32, and X64. The former is a 32-bit architecture, and the latter are both ABIs layered upon the 64-bit architecture. ARM and Intel aren't alone in this, there are others out there doing similarly fun things. Thanks for your time. I'm attaching Dennis' original patch. Just so you can see what it does, not so that you can directly consider that as the solution that will be necessarily eventually in upstream if you can figure out a preferred means to generically handle multiABI. Thanks for your collective time, Jon. P.S. Officially I took the day off today so I might not respond if you ping me on IRC. But email should be working :) [0] Begin TMI. "hardfp" is really a newer ABI extension to the existing ARM ABI. The existing ABI is sometimes referred to as "EABI", but that term is no longer officially used by ARM. When we (the Linux community - we've even agreed between different distributions!) refer to hardfp, we mean the presence of a version 3 VFP unit, and conformance to section 6 of the ARM Architecture Procedure Calling Standard (AAPCS), in which an extension to the ABI is detailed that involves the lower 16 registers of a -d16 or -d32 (but -d16 is all we rely upon) VFPv3. Anyway. It's an ABI that is actually standardized :) [1] The "t" stands for "T"humb2, a compressed in size instruction set that is also supported by ARMv7 Application processors. Using Thumb can buy some increases in performance, but it is a different ISA, and some of the packages involved do not yet build cleanly. Thumb(2) uses a concept known as interworking, in which the PLT (Procedure Linkage Table) is used to trampoline into Thumb2 code at all call points. When we do that, we are always in ARM mode. Consequently, we arbitrarily may switch over to Thumb2 if we care in the future, replacing one library at a time without breaking any existing stuff. Not an ABI issue and not really directly relevant to this thread, but some are confuzzled by the mention of Thumb, and hence this clarification.
diff -uNr rpm-4.9.0-orig//installplatform rpm-4.9.0/installplatform --- rpm-4.9.0-orig//installplatform 2010-12-03 06:11:57.000000000 -0600 +++ rpm-4.9.0/installplatform 2011-08-05 12:25:13.000000000 -0500 @@ -19,7 +19,7 @@ case "$arch" in i[3456]86|pentium[34]|athlon|geode) SUBSTS='s_i386_i386_ s_i386_i486_ s_i386_i586_ s_i386_i686_ s_i386_pentium3_ s_i386_pentium4_ s_i386_athlon_ s_i386_geode_' ;; alpha*) SUBSTS='s_alpha_alpha_ s_alpha_alphaev5_ s_alpha_alphaev56_ s_alpha_alphapca56_ s_alpha_alphaev6_ s_alpha_alphaev67_' ;; - arm*) SUBSTS='s_arm_arm_ s_arm_armv3l_ s_arm_armv4l_ s_arm_armv4tl_ s_arm_armv5tel_ s_arm_armv5tejl_ s_arm_armv6l_ s_arm_armv7l_' ;; + arm*) SUBSTS='s_arm_arm_ s_arm_armv3l_ s_arm_armv4l_ s_arm_armv4tl_ s_arm_armv5tel_ s_arm_armv5tejl_ s_arm_armv6l_ s_arm_armv7l_ s_arm_armv7hl_ s_arm_armv7hnl_' ;; sh4*) SUBSTS='s_sh4_sh4_ s_sh4_sh4a_' ;; sparc*) SUBSTS='s_sparc\(64\|64v\|v9v\|v9\)_sparc_ s_sparc64_sparcv9_;s_sparc\([^v]\|$\)_sparcv9\1_ s_sparcv9_sparc64_;s_sparc\([^6]\|$\)_sparc64\1_' ;; powerpc*|ppc*) SUBSTS='s_ppc64_ppc_ s_ppc\([^6ip]\|$\)_ppc64\1_ s_ppc\([^6ip]\|$\)_ppciseries_ s_ppc\([^6ip]\|$\)_ppcpseries_ s_ppc\([^6ip]\|$\)_ppc64iseries_ s_ppc\([^6ip]\|$\)_ppc64pseries_' ;; diff -uNr rpm-4.9.0-orig//lib/rpmrc.c rpm-4.9.0/lib/rpmrc.c --- rpm-4.9.0-orig//lib/rpmrc.c 2011-08-05 12:23:04.000000000 -0500 +++ rpm-4.9.0/lib/rpmrc.c 2011-08-05 12:25:13.000000000 -0500 @@ -732,6 +732,56 @@ } #endif +#if defined(__linux__) && defined(__arm__) +static int has_neon() +{ + char buffer[4096], *p; + int fd = open("/proc/cpuinfo", O_RDONLY); + if (read(fd, &buffer, sizeof(buffer) - 1) == -1) { + rpmlog(RPMLOG_WARNING, _("read(/proc/cpuinfo) failed\n")); + close(fd); + return 0; + } + close(fd); + + p = strstr(buffer, "Features"); + p = strtok(p, "\n"); + p = strstr(p, "neon"); + p = strtok(p, " "); + if (p == NULL) { + rpmlog(RPMLOG_WARNING, _("/proc/cpuinfo has no 'Features' line\n")); + return 0; + } else if (strcmp(p, "neon") == 0) { + return 1; + } + return 0; +} + +static int has_hfp() +{ + char buffer[4096], *p; + int fd = open("/proc/cpuinfo", O_RDONLY); + if (read(fd, &buffer, sizeof(buffer) - 1) == -1) { + rpmlog(RPMLOG_WARNING, _("read(/proc/cpuinfo) failed\n")); + close(fd); + return 0; + } + close(fd); + + p = strstr(buffer, "Features"); + p = strtok(p, "\n"); + p = strstr(p, "vfpv3"); + p = strtok(p, " "); + if (p == NULL) { + rpmlog(RPMLOG_WARNING, _("/proc/cpuinfo has no 'Features' line\n")); + return 0; + } else if (strcmp(p, "vfpv3") == 0) { + return 1; + } + return 0; +} +#endif + # if defined(__linux__) && defined(__i386__) #include <setjmp.h> @@ -1157,6 +1207,22 @@ } # endif /* sparc*-linux */ +# if defined(__linux__) && defined(__arm__) + { + if (strcmp(un.machine, "armv7l") == 0 ) { + if (has_neon() && has_hfp()) + strcpy(un.machine, "armv7hnl"); + else if (has_hfp()) + strcpy(un.machine, "armv7hl"); + } else if (strcmp(un.machine, "armv6l") == 0 ) { + if (has_neon() && has_hfp()) + strcpy(un.machine, "armv6hnl"); + else if (has_hfp()) + strcpy(un.machine, "armv6hl"); + } + } +# endif /* arm*-linux */ + # if defined(__GNUC__) && defined(__alpha__) { unsigned long amask, implver; diff -uNr rpm-4.9.0-orig//macros.in rpm-4.9.0/macros.in --- rpm-4.9.0-orig//macros.in 2011-08-05 12:23:04.000000000 -0500 +++ rpm-4.9.0/macros.in 2011-08-05 12:25:13.000000000 -0500 @@ -1032,7 +1032,7 @@ #------------------------------------------------------------------------------ # arch macro for all supported ARM processors -%arm armv3l armv4b armv4l armv4tl armv5tel armv5tejl armv6l armv7l +%arm armv3l armv4b armv4l armv4tl armv5tel armv5tejl armv6l armv7l armv7hl armv7nhl #------------------------------------------------------------------------------ # arch macro for all supported Sparc processors diff -uNr rpm-4.9.0-orig//rpmrc.in rpm-4.9.0/rpmrc.in --- rpm-4.9.0-orig//rpmrc.in 2011-08-05 12:23:04.000000000 -0500 +++ rpm-4.9.0/rpmrc.in 2011-08-05 12:26:34.000000000 -0500 @@ -66,6 +66,8 @@ optflags: armv5tejl -O2 -g -march=armv5te optflags: armv6l -O2 -g -march=armv6 optflags: armv7l -O2 -g -march=armv7 +optflags: armv7hl -O2 -g -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mthumb +optflags: armv7hnl -O2 -g -march=armv7-a -mfloat-abi=hard -mfpu=neon -mthumb optflags: atarist -O2 -g -fomit-frame-pointer optflags: atariste -O2 -g -fomit-frame-pointer @@ -140,6 +142,8 @@ arch_canon: armv5tejl: armv5tejl 12 arch_canon: armv6l: armv6l 12 arch_canon: armv7l: armv7l 12 +arch_canon: armv7hl: armv7hl 12 +arch_canon: armv7hnl: armv7hnl 12 arch_canon: m68kmint: m68kmint 13 arch_canon: atarist: m68kmint 13 @@ -248,6 +252,8 @@ buildarchtranslate: armv5tejl: armv5tejl buildarchtranslate: armv6l: armv6l buildarchtranslate: armv7l: armv7l +buildarchtranslate: armv7hl: armv7hl +buildarchtranslate: armv7hnl: armv7hnl buildarchtranslate: atarist: m68kmint buildarchtranslate: atariste: m68kmint @@ -336,6 +342,8 @@ arch_compat: armv4tl: armv4l arch_compat: armv4l: armv3l arch_compat: armv3l: noarch +arch_compat: armv7hnl: armv7hl +arch_compat: armv7hl: noarch arch_compat: atarist: m68kmint noarch arch_compat: atariste: m68kmint noarch @@ -441,6 +449,9 @@ buildarch_compat: armv4l: armv3l buildarch_compat: armv3l: noarch +buildarch_compat: armv7hnl: armv7hl +buildarch_compat: armv7hl: noarch + buildarch_compat: hppa2.0: hppa1.2 buildarch_compat: hppa1.2: hppa1.1 buildarch_compat: hppa1.1: hppa1.0
_______________________________________________ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint