/* Cache Flushing for the PPC: Gforth version Modified by: David N. Williams License: GPL 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. The Gforth version uses one loop. There is an Apple version that uses two loops. This version is under the GPL, version 2 or later, and is part of Gforth, with Copyright (c) 1998 Free Software Foundation, 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 p = (caddr_t) (((long) addr) & -cache_block_size); /* this works for a single-processor PPC 604e, but may have portability problems for other machines; the ultimate solution is a system call, because the architecture is pretty shoddy in this area */ for (; p < (addr+size); p += cache_block_size) /* asm("dcbst 0,%0; sync; icbi 0,%0"::"r"(p)); */ { asm("dcbst 0,%0"::"r"(p)); asm("sync"); asm("icbi 0,%0"::"r"(p)); } /*asm("sync; isync");*/ /* PPC 604e needs the additional sync according to Tim Olson */ asm("sync"); asm("isync"); }