mmap_device_memory

I have a custom dual ported ram device that I am trying to access to no
avail. This device is hung on an ISA bus slot off of a PC104 based
motherboard. The device requires that the address it responds too be loaded
through an IO register. This all seems like pretty simple stuff. Here is
the code.

rc = ThreadCtl(_NTO_TCTL_IO, 0);
if (rc < 0)
printf("\n error %d\n", errno);

rc = mmap_device_io(8, adr);
if (rc < 0)
printf("\n error %d\n", errno);

out8(0x186, 7); // disable interupts
out8(0x187, (0x80 | (0xd0 >> 1))); // Set address of dual ported ram
// this may look
funky but it is correct for the board

shmaddr = 0; // System assigned address
shmaddr = (char *) mmap_device_memory(shmaddr, 512,
PROT_NOCACHE | PROT_READ | PROT_WRITE,
MAP_TYPE, 0xd0000);

printf("\n error %d\n", errno);

shmaddr[0] = ‘a’;
shmaddr[1] = ‘b’;
shmaddr[2] = ‘c’;
tst[0] = shmaddr[0];
tst[1] = shmaddr[1];
tst[2] = shmaddr[2];
printf("\ntest %d, %d, %d, %d\n", shmaddr[510], tst[0], tst[1], tst[2]);

Here is the problem. The result of all calls is success. The result of the
tst[x] assignments are always -1.

I have tried to add a fixed memory area to the startup-bios code (add_mem
function). I can see the memory reported during boot from print_meminfo().
I have verified that the IO port writes work by hardware debugging the
board. What seems to happen is that the 0xd0000 address never actually gets
written or read. The SMEMW signal never triggers on the isa bus.

A few questions have come up as a result of all this.

  1. Why didn’t the write to the allocated address result in a memory protect
    before I modified the startup code.
  2. Why doesn’t the write memory protect ever? regardless of the address
    utilized between 0xa0000 and 0xfffff. Or even specifying nonsense addresses
    beyond the physical address space of the installed memory in the pc104.
  3. Why doesn’t the map_device_memory fail?
  4. Do I need to set up a HWI structure for this device to get it to
    function?
  5. What am I doing wrong here?

Any help would be appreciated.

Brian K. Jackson <bkjackson@agvp.com> wrote:

I have a custom dual ported ram device that I am trying to access to no
avail. This device is hung on an ISA bus slot off of a PC104 based
motherboard. The device requires that the address it responds too be loaded
through an IO register. This all seems like pretty simple stuff. Here is
the code.

Without dissecting your code, it seems unusual to me that the only mechanism
the hardware has to determine what memory range to respond to is the address.

When you boot the hardware up, suppose the contents of this register is
a random value. That would mean that the device maps it’s memory into
a random chunk of address space… hardly likely.

There must be a bit in one of the I/O registers that boots up in an off state
that you must set to enable the device at all. Are you sure you are enabling
this device?


rc = ThreadCtl(_NTO_TCTL_IO, 0);
if (rc < 0)
printf("\n error %d\n", errno);

rc = mmap_device_io(8, adr);
if (rc < 0)
printf("\n error %d\n", errno);

out8(0x186, 7); // disable interupts
out8(0x187, (0x80 | (0xd0 >> 1))); // Set address of dual ported ram
// this may look
funky but it is correct for the board

shmaddr = 0; // System assigned address
shmaddr = (char *) mmap_device_memory(shmaddr, 512,
PROT_NOCACHE | PROT_READ | PROT_WRITE,
MAP_TYPE, 0xd0000);

printf("\n error %d\n", errno);

shmaddr[0] = ‘a’;
shmaddr[1] = ‘b’;
shmaddr[2] = ‘c’;
tst[0] = shmaddr[0];
tst[1] = shmaddr[1];
tst[2] = shmaddr[2];
printf("\ntest %d, %d, %d, %d\n", shmaddr[510], tst[0], tst[1], tst[2]);

Here is the problem. The result of all calls is success. The result of the
tst[x] assignments are always -1.

I have tried to add a fixed memory area to the startup-bios code (add_mem
function). I can see the memory reported during boot from print_meminfo().
I have verified that the IO port writes work by hardware debugging the
board. What seems to happen is that the 0xd0000 address never actually gets
written or read. The SMEMW signal never triggers on the isa bus.

A few questions have come up as a result of all this.

  1. Why didn’t the write to the allocated address result in a memory protect
    before I modified the startup code.
  2. Why doesn’t the write memory protect ever? regardless of the address
    utilized between 0xa0000 and 0xfffff. Or even specifying nonsense addresses
    beyond the physical address space of the installed memory in the pc104.
  3. Why doesn’t the map_device_memory fail?
  4. Do I need to set up a HWI structure for this device to get it to
    function?
  5. What am I doing wrong here?

Any help would be appreciated.

Without dissecting your code, it seems unusual to me that the only
mechanism
the hardware has to determine what memory range to respond to is the
address.

When you boot the hardware up, suppose the contents of this register is
a random value. That would mean that the device maps it’s memory into
a random chunk of address space… hardly likely.

There must be a bit in one of the I/O registers that boots up in an off
state
that you must set to enable the device at all. Are you sure you are
enabling
this device?

The card will not be enabled after reset until an address is written to the
IO port on the card. base port address +1. After that, any address that
matches bits 19-13 on the isa address bus plus SMEMR/W will either read or
write to the onboard ram. Since the SMEMW signal is not transitioning I am
questioning what the mmap_device_memory function is actually doing. You are
welcome to dissect the code, however it is presented as a check to make sure
I am calling the correct functions with generally the correct parameters to
achieve my goals. If this is a stupid programming error I get what I
deserve. I also cannot expect you to diagnose any problems with my
hardware. If the problem lies there I have not done my homework with the
hardware.

pete@qnx.com wrote:

shmaddr = 0; // System assigned address
shmaddr = (char *) mmap_device_memory(shmaddr, 512,
PROT_NOCACHE | PROT_READ | PROT_WRITE,
MAP_TYPE, 0xd0000);

if (shmaddr == MAP_FAILED)

printf("\n error %d\n", errno);

MAP_FAILED = A pointer with all bits set basically -1. In extensive
debugging I have never seen mmap_device_memory() return MAP_FAILED. That is
why I am checking the errno every time. Just to see if it ever records an
error. It never does either. Do you have the source to
mmap_device_memory()? Can you tell me what it actually does?

btw: I have tried
// shmaddr = (char *) mmap(shmaddr, 512,
// PROT_READ | PROT_WRITE,
// MAP_PHYS | MAP_SHARED, NOFD, 0xd0000);
with exactly the same results. I am tempted to believe that
mmap_device_memory() is just a “wrapper” to mmap() call.

<pete@qnx.com> wrote in message news:8tmrfg$ia6$1@nntp.qnx.com

pete@qnx.com > wrote:

shmaddr = 0; // System assigned
address
shmaddr = (char *) mmap_device_memory(shmaddr, 512,
PROT_NOCACHE | PROT_READ | PROT_WRITE,
MAP_TYPE, 0xd0000);

if (shmaddr == MAP_FAILED)

printf("\n error %d\n", errno);

Brian K. Jackson <bkjackson@agvp.com> wrote:

MAP_FAILED = A pointer with all bits set basically -1. In extensive
debugging I have never seen mmap_device_memory() return MAP_FAILED. That is
why I am checking the errno every time. Just to see if it ever records an
error. It never does either. Do you have the source to
mmap_device_memory()? Can you tell me what it actually does?

btw: I have tried
// shmaddr = (char *) mmap(shmaddr, 512,
// PROT_READ | PROT_WRITE,
// MAP_PHYS | MAP_SHARED, NOFD, 0xd0000);
with exactly the same results. I am tempted to believe that
mmap_device_memory() is just a “wrapper” to mmap() call.

I believe it is just a wrapper for mmap. I don’t have the source laying
around. I’m just tossing out ideas as someone who has to map in PCI
device memory all the time… it works for me.