linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* bitops porting question
@ 2000-11-21 12:44 Todd Inglett
  2000-11-21 13:44 ` Todd Inglett
  2000-11-21 14:20 ` Andi Kleen
  0 siblings, 2 replies; 4+ messages in thread
From: Todd Inglett @ 2000-11-21 12:44 UTC (permalink / raw)
  To: linuxppc-dev


All,

I'm working on the 64bit PPC port of linux and need some advice on the
bitops (asm-ppc/bitops.h & arch/ppc/kernel/bitops.c).  I understand that
they are supposed to be "generic" ops, but see a problem with big endian
and word size.

Anyway, the gist of the problem is that when sizeof(int) != sizeof(long)
the operations break down for one reason:  there is no test_bit()
function. Instead, C code is written to test a bit.  For example, in
fs.h we find this macro:

  #define __buffer_state(bh, state)
	(((bh)->b_state & (1UL << BH_##state)) != 0)

Thus, the operations in bitops.c must be written such that this C test
on the bits is valid.  But this is not possible using big endian words
when the length of the bitset is not known.  And little endian is not
the solution because the generated C code does not do little endian
operations, of course.

Consider that b_state in the above example is 64 bits (it is an unsigned
long).  For testing for a lock (BH_Lock == 2) we test bit number 2.
Remember bits are numbered like this (defined by the C usage above) and
stored like this (big endian):

             |61...........0|

So bit #2 will be in the 8th byte of the doubleword.  But the current
set_bit() views 32 bit words like this:

             |31...0|63...32|

So set_bit(2, &b_state) will set a bit in the 4th byte of the virtual
doubleword.  Not good.  A simple fix seems to be to change the
set_bit(), etc, functions to 64 bit.  In general I think this is the
best approach, but consider what will happen with the following:

    int flags;		/* 32 bits */

    set_bit(2, &flags);  /* bad memory ref! */

On a little endian machine this won't happen since the low order bytes
come first.

I probably should take this to the linux kernel list, but thought I
should bring it up here since you guys are no doubt well aware of these
kinds of problems.  It seems the tactical thing to do is to change the
set_bit(), etc, functions to 64 bit but this adds a new restriction that
a bit set must be a multiple of 64 bits in size.  It will become a
requirement that C code tests work only with long values and I'm sure
some drivers will be broken.

A better solution appears to be the addition of a test_bit
function/macro.  Then I can replace it with something that matches the
other functions if necessary.  But then I need to get all the kernel to
use it.  Sigh.

Any advice? :)
--
-todd

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2000-11-21 16:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-11-21 12:44 bitops porting question Todd Inglett
2000-11-21 13:44 ` Todd Inglett
2000-11-21 14:20 ` Andi Kleen
2000-11-21 16:10   ` Todd Inglett

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).