Subject: Re: /bin/sh (?) problem on md-root on ZAO425
To: Steve Woodford <scw@netbsd.org>
From: Richard Earnshaw <rearnsha@buzzard.freeserve.co.uk>
List: port-arm
Date: 08/15/2003 22:51:15
scw@netbsd.org said:
> memcpy.S and friends need to be re-visited for Xscale anyway, which
> I'm planning to do RSN. 

I was pondering over related issues only yesterday.  In particular we have 
some ARM ports which are running builds of the standard libraries that are 
restricted to/tuned for running on the lowest common denominator ARM chip 
(substantially ARM2) even though those platforms will never be implemented 
with more than one CPU.  Most notably these are cats, netwinder and shark, 
all of which only ever use a strongarm processor.  However, other 
platforms (acorn32 will often have a SA processor fitted, and if not, it 
will be arm6/7) there's no need for the libraries to be restricted in 
instruction selection to what was available on arm2.  hpcarm is probably 
restricted to SA based chips, though arm7t/9 might be used on occasion, 
and XScale could also find its way in there.  evbarm will probably only 
ever be used with v4t or later processors, but often with much higher 
architectures.

The i386 ports address a similar issue with floating-point acceleration, 
but there it seems that just a few key functions are replaced.  What I'd 
like to see is the ability to slot in a completely different build of libc 
(same ABI, but different build options) depending on the processor 
detected at boot time.

This brings up two questions:

1) How to represent the information.  It seems that the syntax of 
ld.so.conf only allows switching on a single sysctl variable (so switching 
on both the processor architecture and additional co-processor features 
becomes tricky).  How do we represent both v5e and VFP for library 
selection?

2) How to build the appropriate sets of libraries?  As far as I can tell, 
libc can only be built once.  Is there a way to build another version of 
libc (with a different name, or installed in a different sub-dir) with a 
different set of compiler flags?

My gut feeling for 1) is that we should have a sysctl variable of 
hw.cpuarch which is set to the architecture of the configured processor, 
hence for a SA chip this would be armv4 (except on a RISC PC, where we'd 
need to make the kernel lie and report it as armv3m because of the 
restricted bus architecture).  For arm10e with a VFP processor we'd 
probably have something like

	hw.cpuarch=armv5e+vfp

and for xscale (assuming a Wireless MMX variant)

	hw.cpuarch=armv5e+wmmx

Do we want to split this up a bit and have hw.cpuarch and hw.fullarch with 
the former restricted to the architecture of the processor and the latter 
be that plus the co-processors?  In the majority of cases that would 
simplify ld.so.conf entries since the majority of libraries wouldn't need 
to worry about co-processor variants (only libm, and possibly libc, would 
really benefit from knowing about the presence of VFP for instance).  
Additionally, or alternatively could we make matching rules in ld.so.conf 
use simple regexp type expressions (maybe shell-style globbing)?  Then 
that we could have

libc.so.12	hw.cpuarch	armv[45]*:libc-v4.so.12

which would match any v4 or later processor.

I'm not sure exactly what the solution to 2) is, but my guess is that it's 
largely a matter of makefile hackery.  Maybe it is just a matter of 
splitting the makefile up into a body that defines the files to compile 
and a wrapper (or series of wrappers) that define the build options.

Other folk's thoughts would be welcome here.  Note I'm not proposing 
inventing different ABIs for each platform: An executable built to the 
base ABI and for arm2 would still be able to run anywhere; it's just that 
the shared libraries it picks up would be accelerated for the processor on 
the machine it is running on in this instance.

R.