[comp.sys.m68k] using shared memory to talk to physical memory on a Motorala 147

jody@shell.com (Jody Winston) (12/06/89)

I'm having trouble talking to physical shared memory on a Motorola 147
V/68 system.  I get the id with:

   if ((id = shmget(key, 
		    0x0c, 
		    (IPC_CREAT | IPC_PHYS | IPC_NOCLEAR | IPC_CI),
		    (int)(0xff00 | 0xffff00) )) == -1)
   {
      perror ("shmget");
      exit (-1);
   }
   
And then set the permissions:

   buf.shm_perm.mode = 0666;
   
   if (shmctl(id, IPC_SET, &buf) == -1)
   {
      perror ("shmctl");
      exit (-1);
   }
   
And then map for read and write:

   if ((addr = shmat(id,
		     (char *)0,
		     (0) )) == (char *)-1)
   {
      perror ("shmctl");
      exit (-1);
   }
   
The address is different, than 0xff00, but I expected this due to
virtual to phsyical translation.  When I try to read or write to this
address I get a bus error:

   printf("Address = 0X%X\t Data = 0X%X\n", addr, *addr);



--
Jody Winston		jody@shell.uucp
...!{sun,psuvax1,bcm,rice,decwrl,cs.utexas.edu}!shell!jody
Shell Development Company, Bellaire Research Center
P.O. Box 481, Room 2202, Houston, TX 77001	(Voice: 713 663-2993)

jody@shell.com (Jody Winston) (12/06/89)

The problem was that I forgot that the address returned by shmat is
page aligned.  Using the macros in <sys/immu.h> I found out what was
the byte offset and poof I could talk to the memory.
--
Jody Winston		jody@shell.uucp
...!{sun,psuvax1,bcm,rice,decwrl,cs.utexas.edu}!shell!jody
Shell Development Company, Bellaire Research Center
P.O. Box 481, Room 2202, Houston, TX 77001	(Voice: 713 663-2993)

stevea@mcdclv.UUCP (Steve Alexander) (12/08/89)

In article <JODY.89Dec5121254@robulus.shell.com> jody@shell.com (Jody Winston) writes:
>I'm having trouble talking to physical shared memory on a Motorola 147
>V/68 system.  I get the id with:
>
>   if ((id = shmget(key, 
>		    0x0c, 
>		    (IPC_CREAT | IPC_PHYS | IPC_NOCLEAR | IPC_CI),
>		    (int)(0xff00 | 0xffff00) )) == -1)
...
>And then set the permissions:
>   buf.shm_perm.mode = 0666;
>   if (shmctl(id, IPC_SET, &buf) == -1)
...
>And then map for read and write:
>   if ((addr = shmat(id,
>		     (char *)0,
>		     (0) )) == (char *)-1)
...
>The address is different, than 0xff00, but I expected this due to
>virtual to phsyical translation.  When I try to read or write to this
>address I get a bus error:
>
>   printf("Address = 0X%X\t Data = 0X%X\n", addr, *addr);
>

A couple of points about you program.  It *MUST* run with root
privileges to execute the shmget to create a physical shared memory
segment.  The shmctl to change access mod is unnecessary and could be
accomplished with
    ((IPC_CREAT | IPC_PHYS | IPC_NOCLEAR | IPC_CI) | 0666),
in the shmget call.  See the shmget man page.  The key value MUST be
IPC_PRIVATE.  I assume you have gotten past these points.

I successfully ran your code by changing the physadr parameter of
shmget to 0x0F000.

You say:
>The address is different, than 0xff00, but I expected this due to
>virtual to phsyical translation.
and yet the physical address you specified is:
>		    (int)(0xff00 | 0xffff00)
Which is 0xFFFF00 or 16776960 decimal.  The shmget call will always
round a request for physical memory down to the next 4K byte boundary
(adr = adr &~0xFFF).  This is for consistancy with some 68020 based
Unix implementation's MMU code.  The address returned by shmat is
usually the address of the next 4KB page beyond the end of your
processes data segment.  It has no particular relation to the physical
address. 

>[...]  When I try to read or write to this
>address I get a bus error:
Your reference to *addr refers to physical address 0xFFF000 NOT 0xff00
or even 0xffff00.  Perhaps you don't have any memory at 0xFFF000 !!!

Other possibilities are that the memory at 0xFFF000 does not respond
to the VMEbus address modifier code generated by the shared memory
access.  Normally making a shared memory access to physical memory in
the address range 0-0xFFFFFF will result in an address modifier code
of 'Standard Non-privileged Data Access'.  A physical address range of
0x01000000-0xFFFFFFFF will get an 'Extended Non-privileged Data
Access'.  Motorola's intelligent peripheral boards (mvme332xt,
mvme327, etc) shared memory requires a Supervisory program access.
Control registers for most VME perepherals require Short Privileged
address modifiers.

If the VME address modifier is the problem, you can force the address
modifier generated by the MVME147 by setting the contents on the
control registers on the VMEchip (MVME6000).  See the MVME147 User's
manual for details.
-- 
Steve Alexander             |  Evolution is a very messy business.
Motorola Cleveland          |

jon@ireland.uucp (Jon Doran) (12/12/89)

Yeh, ran into this before...

There is a fourth argument to the shmat library routine, it isn't mentioned
in the bound documentation, but you should be able to find it online.  If
memory serves me correctly it should be the physical address to attach to.

Which brings up another, more serious, problem.

Once you can stomp all over physical memory, one is naturally tempted to
bash on attached VME cards.  There are all sorts of control registers you
can access, in a multi-processor environment you can reboot an attached
processor by altering its control register, you can modify disk controller
registers, etc.  These registers are in a region of the bus address space
known as short I/O.  And the only way I know of to get to them is to write
your own device driver.  Should be the shortest driver ever written...

Sorry I don't have one to post, I don't work on Motorola boards these days.
Perhaps someone could put one together?

Jon