Small gotcha in IA64 definitions of WRITE_REGISTER_XXX

The following code extract works fine in the 32bit build environments, and
also in the AMD64
build environment, but fails with a compilation error in the IA64 build
environment.

if (Ext->InterruptsEnabled)
WRITE_REGISTER_ULONG(Ext->bar0->gcsr, foo);
else
WRITE_REGISTER_ULONG(Ext->bar0->gcsr, bar);

The compilation error is “illegal else without matching if”

if I write it
if (Ext->InterruptsEnabled)
{
WRITE_REGISTER_ULONG(Ext->bar0->gcsr, foo);
}
else
{
WRITE_REGISTER_ULONG(Ext->bar0->gcsr, bar);
}
It works fine under all environments.

The reason is that the functions are defined as functions for the 32 bit and
AMD64 environments, but in the IA64 environment the functions are macros
defined like the following

#define WRITE_REGISTER_XXX(x,y) { \
*(volatile XXX * const)(x) = y; \
KeFlushWriteBuffer(); \
}

Oh, well; I guess I’ll have to remember to use {}.

I note, in passing, that it doesn’t have to be this way. If the macros had
been defined as

#define WRITE_REGISTER_XXX(x,y) (VOID)(*(volatile XXX * const)(x) = y,
KeFlushWriteBuffer())

then my code works with or without enclosing {}.

I thought that the authors of WRITE_REGISTER_XXX had forgotten about the
comma operator until I
looked at the definitions of READ_REGISTER_XXX, where they use it.

Don

The reason is that the functions are defined as functions for the 32 bit and
AMD64 environments, but in the IA64 environment the functions are macros
defined like the following

#define WRITE_REGISTER_XXX(x,y) { \
*(volatile XXX * const)(x) = y; \
KeFlushWriteBuffer(); \
}

They also could have been:

#define WRITE_REGISTER_XXX(x,y) do { \
*(volatile XXX * const)(x) = y; \
KeFlushWriteBuffer(); \
} while (0)

Loren

I regard this as a bug, albeit a small bug, in the DDK. The reason is that
they are documented to be functions, yet are not implemented so that they
can be used everywhere a function call may be used. For instance, If I write

for (WRITE_REGISTER_ULONG(a,b), I = 0; I < 5; ++I) { … }

that will work on 32 bit machines and on AMD64 machines but fail in the IA64
build environment. Your definition as a do … while has similar problems.
If there was no way round, it would be just one of those things; but there
is a way round - define them using the comma operator as I suggested in my
original post.

Don

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Loren Wilton
Sent: 05 February 2005 01:23
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Small gotcha in IA64 definitions of
WRITE_REGISTER_XXX

The reason is that the functions are defined as functions for
the 32 bit and AMD64 environments, but in the IA64
environment the functions are macros defined like the following

#define WRITE_REGISTER_XXX(x,y) { \
*(volatile XXX * const)(x) = y; \
KeFlushWriteBuffer(); \
}

They also could have been:

#define WRITE_REGISTER_XXX(x,y) do { \
*(volatile XXX * const)(x) = y; \
KeFlushWriteBuffer(); \
} while (0)

Loren

Don Ward wrote:

I regard this as a bug, albeit a small bug, in the DDK. The reason is that
they are documented to be functions, yet are not implemented so that they
can be used everywhere a function call may be used.

It may be an annoyance, but I don’t think it’s a bug.

The HAL abstractions, including WRITE_REGISTER/PORT_xxxx and
READ_REGISTER/PORT_xxxx have variously been functions and macros. I
don’t recall the DDK ever saying these were FUNCTIONS per se. We teach
in class (and write in our book) that these functions can be either
functions or macros.

Originally, back on the MIPS, they were macros. A hint to the fact that
they should be treated as macros is that the names are entirely upper
case. Not that this is univesal, lots of things that “look” like
functions are actually macros (witness KeFlushIoBuffers(), or even
IoGetCurrentIrpStackLocation).

So… Not a bug, at least in my opinion. Could the developers have
been a touch more considerate when they wrote the macro? Absolutely.
But the fact that these HAL functions can be implement either as macros
or as C functions is (or at least should be) well known.

Peter
OSR

You’re right. I just looked at the definitions in the DDK and it says MACRO.
Don’t know where I got
the idea it said “function”; maybe in a previous incarnation of the docs,
maybe I just imagined it.

I agree also that it’s a very minor thing. It would be nice to have a
definition that didn’t
have this (mis)feature though - especially as it isn’t necessary.

At least I got a compilation error. I suspect it’s possible to construct
some code that would
compile on both platforms, but would have different semantics. Maybe I
should get out of the habit of
ever writing if statements without {}.

Don

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Peter
Viscarola (OSR)
Sent: 05 February 2005 14:51
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Small gotcha in IA64 definitions of
WRITE_REGISTER_XXX

Don Ward wrote:
> I regard this as a bug, albeit a small bug, in the DDK. The
reason is
> that they are documented to be functions, yet are not
implemented so
> that they can be used everywhere a function call may be used.
>

It may be an annoyance, but I don’t think it’s a bug.

The HAL abstractions, including WRITE_REGISTER/PORT_xxxx and
READ_REGISTER/PORT_xxxx have variously been functions and macros. I
don’t recall the DDK ever saying these were FUNCTIONS per se.
We teach
in class (and write in our book) that these functions can be either
functions or macros.

Originally, back on the MIPS, they were macros. A hint to
the fact that
they should be treated as macros is that the names are entirely upper
case. Not that this is univesal, lots of things that “look” like
functions are actually macros (witness KeFlushIoBuffers(), or even
IoGetCurrentIrpStackLocation).

So… Not a bug, at least in my opinion. Could the developers have
been a touch more considerate when they wrote the macro? Absolutely.
But the fact that these HAL functions can be implement either
as macros
or as C functions is (or at least should be) well known.

Peter
OSR


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@careful.co.uk
To unsubscribe send a blank email to xxxxx@lists.osr.com