Does mmap() align on 32-bit boundary? (Re-posing)

( I posted this last week, it appeared for one day, but for some reason
disappeared. Re-posting… )

Hi,

I am writing a driver and my DMA controller requires that the address of DMA
transfers be aligned on a 32-bit boundary. Does mmap() return an address
that is 32-bit aligned?

Under DOS, the old driver was doing the following:

#define data_transfer_buf_size 32768U
ubyte data_transfer_buf[32771U]; // 3 bytes bigger
ubyte *ptr_data_transfer_buf;

/* check the data_transfer_buf alignment and fix it if needed */
if (FP_OFF(data_transfer_buf) & 0x01)
ptr_data_transfer_buf = &data_transfer_buf[0] + 3;
else
if (FP_OFF(data_transfer_buf) & 0x02)
ptr_data_transfer_buf = &data_transfer_buf[0] + 2;
else
if (FP_OFF(data_transfer_buf) & 0x03)
ptr_data_transfer_buf = &data_transfer_buf[0] + 1;
else
ptr_data_transfer_buf = &data_transfer_buf[0];


Under QNX, I am doing the following:

(attached q1.c)

Is this correct? Do I need it, or does mmap() allocate the DMA buffer
correctly aligned?

Thanks!
Alain Achkar





begin 666 q1.c
M+RH]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3TJ+PT*+RH@475E<W1I
M;VX@=&@=&AE(%%.6"!N97=S9W)O=7 @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" J+PT*+RH@8GD@06QA:6X@06-H:V%R
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" J+PT*+RH@(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" J+PT*+RH@27,@=&AE(&%D9’)E<W,@<F5T=7)N960@8GD@;6UA<"!A
M;&EG;F5D(&]N(&$@,S(M8FET(&)O=6YD87)Y/R @(" @(" @(" @(" J+PT*
M+RH@(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" J+PT*+RH@=&UP7V%D
M9’(@/2!M;6%P*“XN+BD@(” @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" J+PT*+RH@(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" J+PT*+RH@<&AY<U]T;7!?861D<B ](&UP:‘ES*"!T
M;7!?861D<B I.R @+R@8V]N=F5R="!T;R!P:‘ES:6-A;"!A9&1R97-S(" @
M(" @(" J+PT*+RH@(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" J+PT*
M+RH@27,@’!H>7-?=&UP7V%D9’(@)B P># S(#T](# I(#_/R @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" J+PT
+RH@(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" J+PT*+RH]/3T]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T]/3T]/3TJ+PT*#0IC:&%RB @("!T;7!?861D<CL-“F-H87(J
M(” @(’-C<FEP=’-?861D<CL-"@T
<&%D9’)?=" @<&AY<U]T;7!?861D<CL-
M"G!A9&1R7W0@(’!H>7-?<V-R:7!T<U]A9&1R.PT*#0H-“G1Y<&5D968@=6YS
M:6=N960@;&]N9R!53$].1SL-”@T54Q/3D<@4T-225!46UT@/2![#0H@(#!X
M-30P,# P,#!,+" @,’@P,# P,#0V.$PL#0H@(#!X.# X,C P,#!,+" @,’@P
M,# P,# Q.$PL#0H@(#!X,38P,# P,#!,+" @,’@P,# P,# P,$PL#0H@(#!X
M-D$U0S P,#!,+" @,’@P,# P,# P,$PL#0H@(#!X.#@X03 P,#!,+" @,’@P
M,# P,# Y.$PL#0I].PT
#0H-“B\J+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TMB-“B\J($QO860@4T-225!44R!A;F0@86QI9VX@;VX@82!$5T]2
M1”!B;W5N9&%R>2 @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @B-
M"B\J+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
B-"@T
=F]I9”!L
M;V%D7W-C<FEP=" H(‘9O:60@0T>PT*("!U;G-I9VYE9"!A9&IU<W1M96YT
M.PT*#0H@("\J($%L;&]C871E(&$@<&AY2!C;VYT:6=U;W5S(&)U
M9F9E<B J+PT*#0H@("\J(‘9O:60@FUM87 H(‘9O:60J(&%D9’(L#0H@(" @
M(" @(" @("!S:7IE7W0@;&5N+ T
(" @(" @(" @(" @:6YT(’!R;W0L#0H@
M(" @(" @(" @("!I;G0@9FQA9W,L#0H@(" @(" @(" @("!I;G0@9FEL9&5S
M+ T*(" @(" @(" @(" @;V9F7W0@;V9F("D[("HO#0H-"B @=&UP7V%D9’(@
M/2!M;6%P*" P+ T*(" @(" @(" @(" @(#0@R!S:7IE;V8H4T-225!42P-
M"B @(" @(" @(" @("!04D]47U)%041\4%)/5%]74DE417Q04D]47TY/0T%#
M2$4L#0H@(" @(" @(" @(" @34%07U!(65-\34%07T%.3TXL#0H@(" @(" @
M(" @(" @3D]&1"P-“B @(” @(" @(" @(" P(“D[#0H-“B @<&AY<U]T;7!?
M861D<B ](&UP:'ES*”!T;7!?861D<B I.PT*#0H@(&%D:G5S=&UE;G0@(” @
M/2 T(“T@’!H>7-?=&UP7V%D9’(@)B P># S3L@(” @(" O+R!A;&EG;B!I
M="!T;R!$5T]21 T*#0H@(’-C<FEP=’-?861D<B ](“9T;7!?861D<EMA9&IU
M<W1M96YT73L-”@T*("!M96UC<‘DH<V-R:7!T<U]A9&1R+"!30U))4%0L(’-I
M>F5O9BA30U))4%0I(“D[#0I]#0H-“B\J+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TMB-“B\J(%)E=‘5R;G,@=&AE(’!H>7-I8V%L(&%D9’)E<W,@
M;V8@82!V;VED(’!O:6YT97(@(” @(" @(" @(" @(" @(" @(" @(" @(" @
M
B-“B\J+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM
M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TM+2TMB-"@T<&%D
M9’)?=”!M<&AY<R H(‘9O:60J(&%D9’(@0T>PT*(”!O9F8V-%]T(&]F9G-E
M=#L-”@T*("!I9B H(&UE;5]O9F9S970V-“AA9&1R+”!.3T9$+" Q+" F;V9F
M<V5T+" P2 ]/2 M,2 I#0H@('L-“B @(”!R971U<FX@+3$[#0H@('T-"@T
9("!R971U<FX@;V9F<V5T.PT*?0T*#0H-"@``
`
end

Alain Achkar <aachkar@storagequest.com> wrote:

( I posted this last week, it appeared for one day, but for some reason
disappeared. Re-posting… )

Ok, here’s a copy of the answer I posted:

Alain Achkar <aachkar@storagequest.com> wrote:

Hi,

I am writing a driver and my DMA controller requires that the address of DMA
transfers be aligned on a 32-bit boundary. Does mmap() return an address
that is 32-bit aligned?

Yes. You also need physically contiguous – but you have MAP_PHSY|MAP_ANON
which will give you that. Since you are x86, you will also want MAP_NOX64K
and if it is an ISA device you will want MAP_BELOW16M.

To get the physical address, I would suggest mem_offset() (which is
documented) rather than mphys() which isn’t.

-David


QNX Training Services
dagibbs@qnx.com

Actually, in my q1.c, I defined a fuction called mphys() which uses
mem_offset(). I did not know that mphys() was an undocumented function.

Now, regarding the flags, I am using MAP_PHSY|MAP_ANON.
The card is a PCI, so I don’t need MAP_BELOW16M.

What is not clear to me from the documentation is the use of MAP_NOX64K.
When do I need it? What if the memory I am allocating is greater than 64K ?

The chip I am working with (SYM53C875) does not say anything about 64K
boundaries. It has a MOVE instruction which can move 2^24 bytes (16MBytes)
in one instruction from memory to the SCSI bus, which looks like this:

MOVE FROM data_buf, WITH DATA_IN

The bottom line, is, can I allocate 16MB with mmap() and do I need to worry
about 64K boundaries?

Thanks again!
Alain


“David Gibbs” <dagibbs@qnx.com> wrote in message
news:9gnsne$jrv$2@nntp.qnx.com

Alain Achkar <> aachkar@storagequest.com> > wrote:
( I posted this last week, it appeared for one day, but for some reason
disappeared. Re-posting… )


Ok, here’s a copy of the answer I posted:

Alain Achkar <> aachkar@storagequest.com> > wrote:
Hi,

I am writing a driver and my DMA controller requires that the address of
DMA
transfers be aligned on a 32-bit boundary. Does mmap() return an
address
that is 32-bit aligned?

Yes. You also need physically contiguous – but you have
MAP_PHSY|MAP_ANON
which will give you that. Since you are x86, you will also want
MAP_NOX64K
and if it is an ISA device you will want MAP_BELOW16M.

To get the physical address, I would suggest mem_offset() (which is
documented) rather than mphys() which isn’t.

-David


QNX Training Services
dagibbs@qnx.com

Alain Achkar <aachkar@storagequest.com> wrote:

Now, regarding the flags, I am using MAP_PHSY|MAP_ANON.
The card is a PCI, so I don’t need MAP_BELOW16M.

Ok – just warning you as you didn’t specify.

What is not clear to me from the documentation is the use of MAP_NOX64K.
When do I need it? What if the memory I am allocating is greater than 64K ?

If allocating more than 64K, the allocated chunk will, I think, start on
a 64K boundary, but will be allowed to cross.

The chip I am working with (SYM53C875) does not say anything about 64K
boundaries. It has a MOVE instruction which can move 2^24 bytes (16MBytes)
in one instruction from memory to the SCSI bus, which looks like this:

MOVE FROM data_buf, WITH DATA_IN

The bottom line, is, can I allocate 16MB with mmap() and do I need to worry
about 64K boundaries?

I don’t know enough about PC DMA at the hardware level to say for sure –
I know that the 64K boundary/aligned issue was (supposedly) need for PC
DMA. It may be an issue for the AT DMA controller, and a bus-master card
may be ok – or it may just be assumed that if you’re doing DMA, you’ll
know that, and the card’s docs don’t specify.

-David

QNX Training Services
dagibbs@qnx.com

Hi,
I worked whith PC/AT DMA and ISA cards some years ago. The standard DMA
controller (Intel-8237A, single in XT and first in AT) has 16-bit address
registers and 4-bit page registers. Since the current address is a 16-bit
value, it is not possible to cross a 64K boundary with DMA operation. In
addition to the four 8-bit channels of the XT, the AT adds a second DMA
controller (Intel 8237A-5 by cascading) which supports 16-bit DMA channels.
The second DMA controller has 8-bit page registers, but address registers
consist 16 bits. The current address in DMA operation is calculated by :
page_reg<<16+addr_reg<<1. So the max. page size is 128 K (64 K words) and
DMA transfers must not cross a 128K boundary.
Don’t care about boundaries if your chip has no limitations above.

Regards,
Eduard.