Subject: Real physical address of an array in the DATA segme

Please tell me which QNX newsgroup I should post this question to:


Hi,

I am writing a driver for a SYM53C875 SCSI chip and I need to be able to
find out the physical memory address of an array in my DATA segment.

If I have the following declaration:

char my_array [10];

I would like to be able to say:

typedef unsigned long int uquad;

uquad my_array_addr;

my_array_addr = getPhysAddr(my_array);

Now, my_array_addr contains the real physical address where my_array is
located in physical memory.



Under Borland C++ 4.5 (DOS), I saw this function:

/* This function returns the physical 20-bit addres to a far pointer that is

  • passed. This is needed because the c875 only understands true addresses,
  • not segment:offset. */
    uquad
    getPhysAddr(void far * addr)
    {
    return (((uquad)FP_SEG(addr) << 4) + FP_OFF(addr));
    }



    Is there anything in Neutrino equivalent to the FP_SEG and FP_OFF macros?

Thank you!
Alain Achkar
aachkar@storagequest.com

look at mem_offset*


Alain Achkar <aachkar@storagequest.com> wrote:

Please tell me which QNX newsgroup I should post this question to:



Hi,

I am writing a driver for a SYM53C875 SCSI chip and I need to be able to
find out the physical memory address of an array in my DATA segment.

If I have the following declaration:

char my_array [10];

I would like to be able to say:

typedef unsigned long int uquad;

uquad my_array_addr;

my_array_addr = getPhysAddr(my_array);

Now, my_array_addr contains the real physical address where my_array is
located in physical memory.



Under Borland C++ 4.5 (DOS), I saw this function:

/* This function returns the physical 20-bit addres to a far pointer that is

  • passed. This is needed because the c875 only understands true addresses,
  • not segment:offset. */
    uquad
    getPhysAddr(void far * addr)
    {
    return (((uquad)FP_SEG(addr) << 4) + FP_OFF(addr));
    }



    Is there anything in Neutrino equivalent to the FP_SEG and FP_OFF macros?

Thank you!
Alain Achkar
aachkar@storagequest.com


Randy Martin randy@qnx.com
Manager of FAE Group, North America
QNX Software Systems www.qnx.com
175 Terence Matthews Crescent, Kanata, Ontario, Canada K2M 1W8
Tel: 613-591-0931 Fax: 613-591-3579

Under Borland C++ 4.5 (DOS), I saw this function:

/* This function returns the physical 20-bit addres to a far pointer
that is

  • passed. This is needed because the c875 only understands true
    addresses,
  • not segment:offset. */
    uquad
    getPhysAddr(void far * addr)
    {
    return (((uquad)FP_SEG(addr) << 4) + FP_OFF(addr));
    }

You need to do some reading on VM systems. Neutrino is a VM system, and
it would behoove you to understand the issues before writing drivers in
this environment. The code above has nothing to do with obtaining a
physical address from a virtual address, and is essentially misnamed
(segtolinear might be a better name). A VM system will have a function
that gives you the physical address from a virtual address, but it will
be a very much more complex implementation.

Understanding what is actually happening would give you the insight (for
example) to not call the mem_offset function repeatedly (knowing that it
is non-trivial - and in QNX6 actually results in a message being sent to
the memory manager process).

Alain Achkar <aachkar@storagequest.com> wrote:

Please tell me which QNX newsgroup I should post this question to:



Hi,

I am writing a driver for a SYM53C875 SCSI chip and I need to be able to
find out the physical memory address of an array in my DATA segment.

If I have the following declaration:

char my_array [10];

I would like to be able to say:

typedef unsigned long int uquad;

uquad my_array_addr;

my_array_addr = getPhysAddr(my_array);

This can be done – the mem_offset() function will give you this
information, but, this isn’t usually how one wants to architect/write
things under QNX. QNX is a full virtual system, so if you define
my_array[10] as you did above, and got the physical address of
my_array[0], the physical address of my_array[4] might be completely
un-related to the physial address of my_array[3].

So, why do you need the physical address? Usually, it is needed for
passing to a DMA controller – if so, you should actually explicitly
allocate memory in a special way for DMA – it has to be physically
contiguous. (And, if on an x86 platform, there are other issues as
well. DMA memory for ISA needs to be < 16M in physical address for
instance.)

Such memory is allocated with mmap(), passing in appropriate flags.
Check the docs on mmap() for details.

Once you have this DMA-safe memory, you then call mem_offset() to
get the physical address. As mem_offset() is an expensive call,
you usually do this right after allocating the memory, and then save
the physical address away for later use.

Is there anything in Neutrino equivalent to the FP_SEG and FP_OFF macros?

No.

-David

QNX Training Services
dagibbs@qnx.com

Alain Achkar <aachkar@storagequest.com> wrote:

I am writing a driver for a SYM53C875 SCSI chip and I need to be able to
find out the physical memory address of an array in my DATA segment.

[SNIP]

You might also want to check out the Network DDK. It has examples of
setting up a physical memory region to DMA to and from a pcnet network
card.

chris

cdm@qnx.com > “The faster I go, the behinder I get.”

Chris McKillop – Lewis Carroll –
Software Engineer, QSSL
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Thanks for all the responses! They were all very helpful.

I used mmap() to allocate physically contiguous blocks for DMA transfers and
used mem_offset() to get the physical address and pass it to the DMA chip.

Everything is working like a charm!

David Gibbs <dagibbs@qnx.com> wrote in message
news:9dut92$o12$3@nntp.qnx.com

Alain Achkar <> aachkar@storagequest.com> > wrote:
Please tell me which QNX newsgroup I should post this question to:


Hi,

I am writing a driver for a SYM53C875 SCSI chip and I need to be able to
find out the physical memory address of an array in my DATA segment.

If I have the following declaration:

char my_array [10];

I would like to be able to say:

typedef unsigned long int uquad;

uquad my_array_addr;

my_array_addr = getPhysAddr(my_array);

This can be done – the mem_offset() function will give you this
information, but, this isn’t usually how one wants to architect/write
things under QNX. QNX is a full virtual system, so if you define
my_array[10] as you did above, and got the physical address of
my_array[0], the physical address of my_array[4] might be completely
un-related to the physial address of my_array[3].

So, why do you need the physical address? Usually, it is needed for
passing to a DMA controller – if so, you should actually explicitly
allocate memory in a special way for DMA – it has to be physically
contiguous. (And, if on an x86 platform, there are other issues as
well. DMA memory for ISA needs to be < 16M in physical address for
instance.)

Such memory is allocated with mmap(), passing in appropriate flags.
Check the docs on mmap() for details.

Once you have this DMA-safe memory, you then call mem_offset() to
get the physical address. As mem_offset() is an expensive call,
you usually do this right after allocating the memory, and then save
the physical address away for later use.

Is there anything in Neutrino equivalent to the FP_SEG and FP_OFF
macros?

No.

-David

QNX Training Services
dagibbs@qnx.com

One thing which is odd to me, the SYM53C875 chip is supported by
devb-ncr8 driver shipping with system. So unless you’re writing a better
driver you’re reinventing the wheel here :wink:

  • Igor

Alain Achkar wrote:

Thanks for all the responses! They were all very helpful.

I used mmap() to allocate physically contiguous blocks for DMA transfers and
used mem_offset() to get the physical address and pass it to the DMA chip.

Everything is working like a charm!

David Gibbs <> dagibbs@qnx.com> > wrote in message
news:9dut92$o12$> 3@nntp.qnx.com> …
Alain Achkar <> aachkar@storagequest.com> > wrote:
Please tell me which QNX newsgroup I should post this question to:


Hi,

I am writing a driver for a SYM53C875 SCSI chip and I need to be able to
find out the physical memory address of an array in my DATA segment.

If I have the following declaration:

char my_array [10];

I would like to be able to say:

typedef unsigned long int uquad;

uquad my_array_addr;

my_array_addr = getPhysAddr(my_array);

This can be done – the mem_offset() function will give you this
information, but, this isn’t usually how one wants to architect/write
things under QNX. QNX is a full virtual system, so if you define
my_array[10] as you did above, and got the physical address of
my_array[0], the physical address of my_array[4] might be completely
un-related to the physial address of my_array[3].

So, why do you need the physical address? Usually, it is needed for
passing to a DMA controller – if so, you should actually explicitly
allocate memory in a special way for DMA – it has to be physically
contiguous. (And, if on an x86 platform, there are other issues as
well. DMA memory for ISA needs to be < 16M in physical address for
instance.)

Such memory is allocated with mmap(), passing in appropriate flags.
Check the docs on mmap() for details.

Once you have this DMA-safe memory, you then call mem_offset() to
get the physical address. As mem_offset() is an expensive call,
you usually do this right after allocating the memory, and then save
the physical address away for later use.

Is there anything in Neutrino equivalent to the FP_SEG and FP_OFF
macros?

No.

-David

QNX Training Services
dagibbs@qnx.com

The devb-ncr8 is a driver for a SCSI initiator type of device, i.e. a host.
It allows you to communicate with SCSI targets, such as hard-disks.

I am writing a SCSI target driver, which allows you to emulate a SCSI
device, such as a hard-disk.

Also, the devb-ncr8 is very limited. It does not support SCSI pass-through,
so you cannot send specific SCSI commands, say for instance, to an optical
jukebox, or a DVD jukebox. If QSSL were kind enough to publish the source
code for devb-ncr8 as they did for other DDKs, it would be a great help to
me.

Alain.

“Igor Kovalenko” <Igor.Kovalenko@motorola.com> wrote in message
news:3B057723.5BD68C28@motorola.com

One thing which is odd to me, the SYM53C875 chip is supported by
devb-ncr8 driver shipping with system. So unless you’re writing a better
driver you’re reinventing the wheel here > :wink:

  • Igor

Alain Achkar wrote:

Thanks for all the responses! They were all very helpful.

I used mmap() to allocate physically contiguous blocks for DMA transfers
and
used mem_offset() to get the physical address and pass it to the DMA
chip.

Everything is working like a charm!

David Gibbs <> dagibbs@qnx.com> > wrote in message
news:9dut92$o12$> 3@nntp.qnx.com> …
Alain Achkar <> aachkar@storagequest.com> > wrote:
Please tell me which QNX newsgroup I should post this question to:


Hi,

I am writing a driver for a SYM53C875 SCSI chip and I need to be
able to
find out the physical memory address of an array in my DATA segment.

If I have the following declaration:

char my_array [10];

I would like to be able to say:

typedef unsigned long int uquad;

uquad my_array_addr;

my_array_addr = getPhysAddr(my_array);

This can be done – the mem_offset() function will give you this
information, but, this isn’t usually how one wants to architect/write
things under QNX. QNX is a full virtual system, so if you define
my_array[10] as you did above, and got the physical address of
my_array[0], the physical address of my_array[4] might be completely
un-related to the physial address of my_array[3].

So, why do you need the physical address? Usually, it is needed for
passing to a DMA controller – if so, you should actually explicitly
allocate memory in a special way for DMA – it has to be physically
contiguous. (And, if on an x86 platform, there are other issues as
well. DMA memory for ISA needs to be < 16M in physical address for
instance.)

Such memory is allocated with mmap(), passing in appropriate flags.
Check the docs on mmap() for details.

Once you have this DMA-safe memory, you then call mem_offset() to
get the physical address. As mem_offset() is an expensive call,
you usually do this right after allocating the memory, and then save
the physical address away for later use.

Is there anything in Neutrino equivalent to the FP_SEG and FP_OFF
macros?

No.

-David

QNX Training Services
dagibbs@qnx.com

Ok, I see. Yes I know how limited NCR8 driver is. They are not publishing it
because they are rewriting block I/O subsystem. The new one allegedly will
support CAM inteface, have common buffer cache and who knows what else.
Looks like io-blk will become executable rather than DLL, while devb-xxx
driver might become DDLs (my guess).

  • igor

“Alain Achkar” <aachkar@storagequest.com> wrote in message
news:9gr7tv$6c8$1@inn.qnx.com

The devb-ncr8 is a driver for a SCSI initiator type of device, i.e. a
host.
It allows you to communicate with SCSI targets, such as hard-disks.

I am writing a SCSI target driver, which allows you to emulate a SCSI
device, such as a hard-disk.

Also, the devb-ncr8 is very limited. It does not support SCSI
pass-through,
so you cannot send specific SCSI commands, say for instance, to an optical
jukebox, or a DVD jukebox. If QSSL were kind enough to publish the source
code for devb-ncr8 as they did for other DDKs, it would be a great help to
me.

Alain.

“Igor Kovalenko” <> Igor.Kovalenko@motorola.com> > wrote in message
news:> 3B057723.5BD68C28@motorola.com> …
One thing which is odd to me, the SYM53C875 chip is supported by
devb-ncr8 driver shipping with system. So unless you’re writing a better
driver you’re reinventing the wheel here > :wink:

  • Igor

Alain Achkar wrote:

Thanks for all the responses! They were all very helpful.

I used mmap() to allocate physically contiguous blocks for DMA
transfers
and
used mem_offset() to get the physical address and pass it to the DMA
chip.

Everything is working like a charm!

David Gibbs <> dagibbs@qnx.com> > wrote in message
news:9dut92$o12$> 3@nntp.qnx.com> …
Alain Achkar <> aachkar@storagequest.com> > wrote:
Please tell me which QNX newsgroup I should post this question to:


Hi,

I am writing a driver for a SYM53C875 SCSI chip and I need to be
able to
find out the physical memory address of an array in my DATA
segment.

If I have the following declaration:

char my_array [10];

I would like to be able to say:

typedef unsigned long int uquad;

uquad my_array_addr;

my_array_addr = getPhysAddr(my_array);

This can be done – the mem_offset() function will give you this
information, but, this isn’t usually how one wants to
architect/write
things under QNX. QNX is a full virtual system, so if you define
my_array[10] as you did above, and got the physical address of
my_array[0], the physical address of my_array[4] might be completely
un-related to the physial address of my_array[3].

So, why do you need the physical address? Usually, it is needed for
passing to a DMA controller – if so, you should actually explicitly
allocate memory in a special way for DMA – it has to be physically
contiguous. (And, if on an x86 platform, there are other issues as
well. DMA memory for ISA needs to be < 16M in physical address for
instance.)

Such memory is allocated with mmap(), passing in appropriate flags.
Check the docs on mmap() for details.

Once you have this DMA-safe memory, you then call mem_offset() to
get the physical address. As mem_offset() is an expensive call,
you usually do this right after allocating the memory, and then save
the physical address away for later use.

Is there anything in Neutrino equivalent to the FP_SEG and FP_OFF
macros?

No.

-David

QNX Training Services
dagibbs@qnx.com