[comp.sys.m68k] mc68040 I/D coherency

tac@cs.brown.edu (Theodore A. Camus) (06/01/90)

A quick question :

  The mc68040 apparently has separate on-chip instruction and data 
caches (4k each).  I was curious what method they chose to solve the
problem of self-modified code, where the D cache has a copy of a 
modified instruction, but the I cache has an old copy.  

Just curious - 
   - Ted

(p.s. yes I know it is bad practice.  Disallowing it is a valid method,
      just an inflexible one.)

  CSnet:     tac@cs.brown.edu                          Ted Camus  
  ARPAnet:   tac%cs.brown.edu@relay.cs.net             Box 1910 CS Dept
  BITnet:    tac@browncs.BITNET                        Brown University
  "An ounce of example is worth a pound of theory."    Providence, RI 02912

dolf@idca.tds.PHILIPS.nl (Dolf Grunbauer) (06/01/90)

In article <41463@brunix.UUCP> tac@cs.brown.edu (Theodore A. Camus) writes:
=  The mc68040 apparently has separate on-chip instruction and data 
=caches (4k each).  I was curious what method they chose to solve the
=problem of self-modified code, where the D cache has a copy of a 
=modified instruction, but the I cache has an old copy.  

There is no detection of this situation on the MC68040. You should avoid
it by flushing & disabling the caches and hoping the modified instruction
is not already in the pipeline.
-- 
Dolf Grunbauer      Tel: +31 55 433233 Internet dolf@idca.tds.philips.nl
Philips Information Systems            UUCP     ...!mcsun!philapd!dolf
Dept. BS Software,  P.O. Box 245, 7300 AE Apeldoorn, The Netherlands 
read: error in reading .signature

valentin@cbmvax.commodore.com (Valentin Pepelea) (06/01/90)

In article <41463@brunix.UUCP> tac@cs.brown.edu (Theodore A. Camus) writes:
>
>   The mc68040 apparently has separate on-chip instruction and data 
> caches (4k each).  I was curious what method they chose to solve the
> problem of self-modified code, where the D cache has a copy of a 
> modified instruction, but the I cache has an old copy.  

'They' chose not to support this practice at all. Writing self modifying
code (Ahem - self distructing code) is not just difficult, it's darn well
impossible on most systems.

The only solution I can see for you is to flush the instruction cache for the
particular address in question, and execute a NOP to synchronise the pipeline.

Geez, I can't believe I am telling you how to write bad code! Hopefully I
missed some subtle quirk of the '040 which would make this practice impossible
under any circumstances.

Valentin
-- 
The Goddess of democracy? "The tyrants     Name:    Valentin Pepelea
may distroy a statue,  but they cannot     Phone:   (215) 431-9327
kill a god."                               UseNet:  cbmvax!valentin@uunet.uu.net
             - Ancient Chinese Proverb     Claimer: I not Commodore spokesman be

dolf@idca.tds.PHILIPS.nl (Dolf Grunbauer) (06/01/90)

In article <12055@cbmvax.commodore.com> valentin@cbmvax (Valentin Pepelea) writes:
<'They' chose not to support this practice at all. Writing self modifying
<code (Ahem - self distructing code) is not just difficult, it's darn well
<impossible on most systems.
I agree that writing self modifying code should be very hard to be made.

<Geez, I can't believe I am telling you how to write bad code! Hopefully I
<missed some subtle quirk of the '040 which would make this practice impossible
<under any circumstances.
No you don't want it to make it impossible under *any* circumstances. How
about your favorite run-time debugger like 'sdb' or 'adb' or whatever debugger
you are using ? If you put a breakpoint somewhere in the code, the instruction
is replaced by a special trap or someting alike. This is self modifying code.
-- 
Dolf Grunbauer      Tel: +31 55 433233 Internet dolf@idca.tds.philips.nl
Philips Information Systems            UUCP     ...!mcsun!philapd!dolf
Dept. BS Software,  P.O. Box 245, 7300 AE Apeldoorn, The Netherlands 
read: error in reading .signature

kdq@demott.COM (Kevin D. Quitt) (06/02/90)

In article <765@ssp11.idca.tds.philips.nl> dolf@idca.tds.PHILIPS.nl (Dolf Grunbauer) writes:
...
>No you don't want it to make it impossible under *any* circumstances. How
>about your favorite run-time debugger like 'sdb' or 'adb' or whatever debugger
>you are using ? If you put a breakpoint somewhere in the code, the instruction
>is replaced by a special trap or someting alike. This is self modifying code.

    It should be impossible for any user-level code.  Priveleged code like
a debugger must be smart enough to invalidate the cache, and that has nothing
to do with I vs D.


-- 

 _
Kevin D. Quitt         Manager, Software Development    34 12 N  118 27 W
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  
MODEM (818) 997-4496 Telebit PEP last      demott!kdq   kdq@demott.com

      96.37% of the statistics used in arguments are made up.

bryce@cbmvax.commodore.com (Bryce Nesbitt) (06/02/90)

In article <> valentin@cbmvax (Valentin Pepelea) writes:
>'They' chose not to support this practice at all. Writing self modifying
>code (Ahem - self distructing code) is not just difficult, it's darn well
>impossible on most systems.

Darn well common.  Consider loading code from disk.  Or worse
yet, a relocating loader.  The case is identical.


-- 
|\_/|  . "ACK!, NAK!, EOT!, SOH!"  "Lawyers: America's untapped export market."
{X o} .     Bryce Nesbitt, Commodore-Amiga, Inc.
 (")        BIX: bnesbitt
  U	    USENET: bryce@commodore.COM -or- uunet!cbmvax!bryce

valentin@cbmvax.commodore.com (Valentin Pepelea) (06/02/90)

In article <12131@cbmvax.commodore.com> bryce@cbmvax (Bryce Nesbitt) writes:
>In article <> valentin@cbmvax (Valentin Pepelea) writes:
>>
>> 'They' chose not to support this practice at all. Writing self modifying
>> code (Ahem - self distructing code) is not just difficult, it's darn well
>> impossible on most systems.
>
> Darn well common.  Consider loading code from disk.  Or worse
> yet, a relocating loader.  The case is identical.

Loading code from disk, and even a relocating loader may run in supervisor mode,
where it has access to the internal registers which cause the cache to
clear or flush out.

On most Unix implementations, user code may never access supervisor-only
registers. And user code may not even write instruction space, particularly
not through a data manipulation instruction.

You still have a long way to go until you can refute my theories, Bryce.

Valentin
-- 
The Goddess of democracy? "The tyrants     Name:    Valentin Pepelea
may distroy a statue,  but they cannot     Phone:   (215) 431-9327
kill a god."                               UseNet:  cbmvax!valentin@uunet.uu.net
             - Ancient Chinese Proverb     Claimer: I not Commodore spokesman be

Christopher.Hoover@CS.CMU.EDU (06/03/90)

kdq@demott.COM (Kevin D. Quitt) writes:
> 
>     It should be impossible for any user-level code.  Priveleged code like
> a debugger must be smart enough to invalidate the cache, and that has nothing
> to do with I vs D.
> 

No, user-level code must be able to flush the I-cache.  Languages like
Lisp which manage their heaps using a copying garbage collector need
to flush the I-cache after a GC as objects containing code may be
moved by the garbage collector.

-- Chris.
(Christopher.Hoover@CS.CMU.EDU)

kdq@demott.COM (Kevin D. Quitt) (06/03/90)

In article <YaO23DC00hsj0IpwY5@cs.cmu.edu> Christopher.Hoover@CS.CMU.EDU writes:
>kdq@demott.COM (Kevin D. Quitt) writes:
>> 
>>     It should be impossible for any user-level code.  Priveleged code like
>> a debugger must be smart enough to invalidate the cache, and that has nothing
>> to do with I vs D.
>> 
>
>No, user-level code must be able to flush the I-cache.  Languages like
>Lisp which manage their heaps using a copying garbage collector need
>to flush the I-cache after a GC as objects containing code may be
>moved by the garbage collector.
>

    Yes, they do.  What does this have to do with user-level code? If
the code in interpreted, moving it doesn't matter.  I don't think
compiled lisp code (that is actually compiled to machine code) is moved
(not in the lisps I've written).  In that case, though, the GC should
run setuid to do its very-machine-dependent memory manipulation. 

    I don't mean to be a pedant.  What I'm trying to say is that cache
management, along with memory management, belong to the operating
system.  Just as there are calls to allow a user program to manipulate
memory mapping, there should be calls for cache control (possibly just
invalidate_my_cache).



-- 
 _
Kevin D. Quitt         Manager, Software Development    34 12 N  118 27 W
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  
MODEM (818) 997-4496 Telebit PEP last      demott!kdq   kdq@demott.com

      96.37% of the statistics used in arguments are made up.

daveh@cbmvax.commodore.com (Dave Haynie) (06/12/90)

In article <12131@cbmvax.commodore.com> bryce@cbmvax (Bryce Nesbitt) writes:
>In article <> valentin@cbmvax (Valentin Pepelea) writes:
>>'They' chose not to support this practice at all. Writing self modifying
>>code (Ahem - self distructing code) is not just difficult, it's darn well
>>impossible on most systems.

>Darn well common.  Consider loading code from disk.  Or worse
>yet, a relocating loader.  The case is identical.

That's not self-modifying code.  The code, as loaded, is of course data-space
information.  The loader performs the modifications, and then at some point
this data-space magically is converted to instruction-space.  The only thing
such a transform can affect is a copyback data cache.  

The problem with self modifying code, or something similar, is going from 
I-space to D-space and then immediately back to I-space.  It's quite easy for
such a case to wind up with stale I-space code.  This problem isn't only 
seen with self-modifying code, but it's most likely to occur with self 
modifying code, since the I->D->I transform must take place without flushing
the I cache for a problem to occur.

Some system simplify the problem by flushing caches when they change from 
Supervisor to User space.  That will, for example, solve the copyback problem
mentioned in the first case automatically for systems like UNIX in which the
loader is always a Kernel routine.  Other systems may have to explicitly
flush the data cache or possibly use only write-through caching.

>{X o} .     Bryce Nesbitt, Commodore-Amiga, Inc.


-- 
Dave Haynie Commodore-Amiga (Amiga 3000) "The Crew That Never Rests"
   {uunet|pyramid|rutgers}!cbmvax!daveh      PLINK: hazy     BIX: hazy
	"I have been given the freedom to do as I see fit" -REM

bryce@cbmvax.commodore.com (Bryce Nesbitt) (06/12/90)

In article <12558@cbmvax.commodore.com> daveh@cbmvax (Dave Haynie) writes:
>That's not self-modifying code.  The code, as loaded, is of course data-space
>information.  The loader performs the modifications, and then at some point
>this data-space magically is converted to instruction-space.  The only thing
>such a transform can affect is a copyback data cache.  

Except, of course, if the area in question was used for instructions previously
(back to the standard I->D->I problem, though down to a one-in-a-zillion case).
The I cache needs to be accounted for as part of the load operation, part of
relocation, or otherwise.  DMA/Bus snooping would help here, since (it seems)
a snoop affects both I and D caches.

The 68040 manual is a bit vauge on certain snooping and serialization issues.
One can infer that a snoop affects both caches, but one must take on faith that
when section 8 talks about "non-cacheable I/O" it really means "cache inhibited,
nonserialized".  A number of subtle points are not covered, like what happens
for a non-aligned access to a serialized page.


-- 
|\_/|  . "ACK!, NAK!, EOT!, SOH!"  "Lawyers: America's untapped export market."
{X o} .     Bryce Nesbitt, Commodore-Amiga, Inc.
 (")        BIX: bnesbitt
  U	    USENET: bryce@commodore.COM -or- uunet!cbmvax!bryce