From: Timur Tabi <hidden> Date: 2007-08-15 21:31:01
This patch adds the setmaskedbits_xxx() macros, which are used to set a
multiple-bit bit pattern in a register. The macros include a mask, which
zeros the respective bits before applying the value via a bitwise-OR.
There are big-endian and little-endian versions for 8, 16, 32, and 64 bits.
These new macros are useful because the setbits macros can only be used
to set single-bit fields. For example, if you have a 32-bit register
where bits 17-20 need to be set to 0100, you would do
setmaskedbits_be32(p, 4 << 11, 0xF << 11).
Signed-off-by: Timur Tabi <redacted>
---
Updated the changelog to include a reason why you'd want these macros.
I have a number of new SOC device drivers coming up that will use these
macros, if this patch is accepted.
include/asm-powerpc/io.h | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
From: Kumar Gala <hidden> Date: 2007-08-16 03:21:05
On Aug 15, 2007, at 4:30 PM, Timur Tabi wrote:
This patch adds the setmaskedbits_xxx() macros, which are used to
set a
multiple-bit bit pattern in a register. The macros include a mask,
which
zeros the respective bits before applying the value via a bitwise-OR.
There are big-endian and little-endian versions for 8, 16, 32, and
64 bits.
These new macros are useful because the setbits macros can only be
used
to set single-bit fields. For example, if you have a 32-bit register
where bits 17-20 need to be set to 0100, you would do
setmaskedbits_be32(p, 4 << 11, 0xF << 11).
Signed-off-by: Timur Tabi <redacted>
---
Updated the changelog to include a reason why you'd want these macros.
I have a number of new SOC device drivers coming up that will use
these
macros, if this patch is accepted.
Can you post a driver that uses this. I'm interested in seeing what
the readability is really like using these macros.
- k
From: Michael Ellerman <hidden> Date: 2007-08-16 03:55:48
On Wed, 2007-08-15 at 16:30 -0500, Timur Tabi wrote:
quoted hunk
This patch adds the setmaskedbits_xxx() macros, which are used to set a
multiple-bit bit pattern in a register. The macros include a mask, which
zeros the respective bits before applying the value via a bitwise-OR.
There are big-endian and little-endian versions for 8, 16, 32, and 64 bits.
These new macros are useful because the setbits macros can only be used
to set single-bit fields. For example, if you have a 32-bit register
where bits 17-20 need to be set to 0100, you would do
setmaskedbits_be32(p, 4 << 11, 0xF << 11).
Signed-off-by: Timur Tabi <redacted>
---
Updated the changelog to include a reason why you'd want these macros.
I have a number of new SOC device drivers coming up that will use these
macros, if this patch is accepted.
include/asm-powerpc/io.h | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
Can you extract the masking logic, rather than repeating it 7 times:
#define maskbits(a, v, m) ((a) & ~(m) | (v))
And if you're going to the trouble of making a macro, why not make it a
bit more useful and have it check that the value and the mask match, ie:
(v & ~m == 0)
Final random thought, you could make the size/endian an argument:
#define setmaskedbits(a, v, m, s) out_##s((a), (in_##s(a) & ~(m) | (v))
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
Can you extract the masking logic, rather than repeating it 7 times:
#define maskbits(a, v, m) ((a) & ~(m) | (v))
And if you're going to the trouble of making a macro, why not make it a
bit more useful and have it check that the value and the mask match, ie:
(v & ~m == 0)
Final random thought, you could make the size/endian an argument:
#define setmaskedbits(a, v, m, s) out_##s((a), (in_##s(a) & ~(m) | (v))
For readability, you can change the parameter names `v' and `m' to e.g. `set'
and `clear' (or `clr'), so people don't have to look through the actual
definitions to know which one comes first?
With kind regards,
Geert Uytterhoeven
Software Architect
Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
Phone: +32 (0)2 700 8453
Fax: +32 (0)2 700 8622
E-mail: Geert.Uytterhoeven@sonycom.com
Internet: http://www.sony-europe.com/
Sony Network and Software Technology Center Europe
A division of Sony Service Centre (Europe) N.V.
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium
VAT BE 0413.825.160 · RPR Brussels
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619
From: Timur Tabi <hidden> Date: 2007-08-16 15:18:23
Kumar Gala wrote:
Can you post a driver that uses this. I'm interested in seeing what the
readability is really like using these macros.
I do not yet have any drivers ready, but I can give you an example:
setmaskedbits_be32(&uccp->gumr_l,
UCC_SLOW_GUMR_L_MODE_QMC | UCC_SLOW_GUMR_L_TDCR_1 |
UCC_SLOW_GUMR_L_RDCR_16,
UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK |
UCC_SLOW_GUMR_L_RDCR_MASK);
setmaskedbits_be32(&uccp->gumr_h,
UCC_SLOW_GUMR_H_SUART | UCC_SLOW_GUMR_H_TRX |
UCC_SLOW_GUMR_H_TTX, UCC_SLOW_GUMR_H_RFW);
The alternative to using a macro like this is to do this:
reg = in_be32(p);
reg &= ~some-mask-bits;
reg |= some-other-bits;
out_be32(p, reg);
--
Timur Tabi
Linux Kernel Developer @ Freescale
From: Kumar Gala <hidden> Date: 2007-08-16 15:20:21
On Aug 16, 2007, at 10:18 AM, Timur Tabi wrote:
Kumar Gala wrote:
quoted
Can you post a driver that uses this. I'm interested in seeing
what the readability is really like using these macros.
I do not yet have any drivers ready, but I can give you an example:
setmaskedbits_be32(&uccp->gumr_l,
UCC_SLOW_GUMR_L_MODE_QMC | UCC_SLOW_GUMR_L_TDCR_1 |
UCC_SLOW_GUMR_L_RDCR_16,
UCC_SLOW_GUMR_L_MODE_MASK |
UCC_SLOW_GUMR_L_TDCR_MASK |
UCC_SLOW_GUMR_L_RDCR_MASK);
setmaskedbits_be32(&uccp->gumr_h,
UCC_SLOW_GUMR_H_SUART | UCC_SLOW_GUMR_H_TRX |
UCC_SLOW_GUMR_H_TTX, UCC_SLOW_GUMR_H_RFW);
Can you also show what the UCC_SLOW* values look like.
The alternative to using a macro like this is to do this:
reg = in_be32(p);
reg &= ~some-mask-bits;
reg |= some-other-bits;
out_be32(p, reg);
--
Timur Tabi
Linux Kernel Developer @ Freescale
Can you also show what the UCC_SLOW* values look like.
The second example is actually a trick that lets me set some bits and clear
others in one shot, so for the gumr_h register, all of the above values are
single bits. I guess that's not a good example.
For gumr_l, we have:
#define UCC_SLOW_GUMR_L_TDCR_MASK 0x00030000
#define UCC_SLOW_GUMR_L_TDCR_32 0x00030000
#define UCC_SLOW_GUMR_L_TDCR_16 0x00020000
#define UCC_SLOW_GUMR_L_TDCR_8 0x00010000
#define UCC_SLOW_GUMR_L_TDCR_1 0x00000000
#define UCC_SLOW_GUMR_L_RDCR_MASK 0x0000c000
#define UCC_SLOW_GUMR_L_RDCR_32 0x0000c000
#define UCC_SLOW_GUMR_L_RDCR_16 0x00008000
#define UCC_SLOW_GUMR_L_RDCR_8 0x00004000
#define UCC_SLOW_GUMR_L_RDCR_1 0x00000000
#define UCC_SLOW_GUMR_L_MODE_MASK 0x0000000F
#define UCC_SLOW_GUMR_L_MODE_BISYNC 0x00000008
#define UCC_SLOW_GUMR_L_MODE_AHDLC 0x00000006
#define UCC_SLOW_GUMR_L_MODE_UART 0x00000004
#define UCC_SLOW_GUMR_L_MODE_QMC 0x00000002
So for example, I could not use setbits32 to set UCC_SLOW_GUMR_L_RDCR_16 (10)
if it was currently UCC_SLOW_GUMR_L_RDCR_32 (11).
--
Timur Tabi
Linux Kernel Developer @ Freescale
From: Timur Tabi <hidden> Date: 2007-08-16 15:27:42
Michael Ellerman wrote:
And if you're going to the trouble of making a macro, why not make it a
bit more useful and have it check that the value and the mask match, ie:
(v & ~m == 0)
What should I do if it fails this check?
Final random thought, you could make the size/endian an argument:
#define setmaskedbits(a, v, m, s) out_##s((a), (in_##s(a) & ~(m) | (v))
Hmmm.... the only thing wrong with that is that it would allow be64 on a
32-bit platform (i.e. no __power64__ protection). But that's minor.
--
Timur Tabi
Linux Kernel Developer @ Freescale
Can you also show what the UCC_SLOW* values look like.
The second example is actually a trick that lets me set some bits and clear
others in one shot, so for the gumr_h register, all of the above values are
single bits. I guess that's not a good example.
From: Timur Tabi <hidden> Date: 2007-08-16 17:46:12
Benjamin Herrenschmidt wrote:
quoted
The second example is actually a trick that lets me set some bits and clear
others in one shot, so for the gumr_h register, all of the above values are
single bits. I guess that's not a good example.
Such tricks deserve at least a comment.
Would it be better if the function were called setclrbits_xxx(), and advertise
that it can be used to set multi-bit fields *and* set and clear bits at the
same time?
--
Timur Tabi
Linux Kernel Developer @ Freescale