/* Cache Flushing for the PPC: Apple version Modified by: David N. Williams License: Apple PSL First revision: June 18, 2001 Last revision: October 24, 2001 This code expresses an algorithm for maintaining coherence in the PPC instruction fetching mechanism when the processor modifies a memory location that may be in the instruction cache, such as described in Motorola's "MPC750 RISC Microprocessor User's Manual", August, 1997, page 3.4. We quote the algorithm: dcbst #update memory sync #wait for update icbi #remove (invalidate) copy in instruction cache sync #wait for ICBI operation to be globally performed isync #remove copy in own instruction buffer Since the possible expressions of this algorithm are limited, equivalent, and obvious, we believe this code cannot be excluded from the public domain. This Apple version, from Darwin xnu cache.s, uses two loops. There is a Gforth version that uses one loop. This version is under the Apple Public Source License, version 1.1, with Copyright (c) Apple Computer, Inc. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include #include /* The name is from an AIX (4.3) call (thanks to Dan Prener for this information). (dnw 24Oct01): The code below is expected to work with PPC's through the G4. It might also work for multiple processors, but we haven't checked that. GNU uses different line separator characters for different systems in PPC asm("...;...") multiple assembly language statements. The simplest way around this is to avoid multiple statements. */ void _sync_cache_range(caddr_t addr, size_t size) { size_t cache_block_size = 32; caddr_t p0 = (caddr_t) (((long) addr) & -cache_block_size); caddr_t p = p0; for (; p < (addr+size); p += cache_block_size) asm("dcbst 0,%0"::"r"(p)); asm("sync"); for (p = p0; p < (addr+size); p += cache_block_size) asm("icbi 0,%0"::"r"(p)); asm("sync"); asm("isync"); }