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

Reply via email to