/* * (C) Copyright 2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include #include #include #define CACHE_CMD_ENABLE 0x02000000 #define CACHE_CMD_DISABLE 0x04000000 #define CACHE_CMD_LOAD_LOCK 0x06000000 #define CACHE_CMD_UNLOCK_LINE 0x08000000 #define CACHE_CMD_UNLOCK_ALL 0x0A000000 #define CACHE_CMD_INVALIDATE 0x0C000000 #define SPEED_PLPRCR_WAIT_5CYC 150 #define _CACHE_ALIGN_SIZE 16 .text .align 2 .globl plprcr_write_866 /* * void plprcr_write_866 (long plprcr) * Write PLPRCR, including workaround for device errata SIU4 and SIU9. */ plprcr_write_866: mfspr r10, LR /* save the Link Register value */ /* turn instruction cache on (no MMU required for instructions) */ lis r4, CACHE_CMD_ENABLE@h ori r4, r4, CACHE_CMD_ENABLE@l mtspr IC_CST, r4 isync /* clear IC_CST error bits */ mfspr r4, IC_CST bl plprcr_here plprcr_here: mflr r5 /* calculate relocation offset */ lis r4, plprcr_here@h ori r4, r4, plprcr_here@l sub r5, r5, r4 /* calculate first address of this function */ lis r6, plprcr_write_866@h ori r6, r6, plprcr_write_866@l add r6, r6, r5 /* calculate end address of this function */ lis r7, plprcr_end@h ori r7, r7, plprcr_end@l add r7, r7, r5 /* load and lock code addresses */ mr r5, r6 plprcr_loop: mtspr IC_ADR, r5 addi r5, r5, _CACHE_ALIGN_SIZE /* increment by one line */ lis r4, CACHE_CMD_LOAD_LOCK@h ori r4, r4, CACHE_CMD_LOAD_LOCK@l mtspr IC_CST, r4 isync cmpw r5, r7 blt plprcr_loop /* IC_CST error bits not evaluated */ /* switch PLPRCR */ mfspr r4, IMMR /* read IMMR */ rlwinm r4, r4, 0, 0, 15 /* only high 16 bits count */ /* write sequence according to MPC866 Errata */ stw r3, PLPRCR(r4) isync lis r3, SPEED_PLPRCR_WAIT_5CYC@h ori r3, r3, SPEED_PLPRCR_WAIT_5CYC@l plprcr_wait: cmpwi r3, 0 beq plprcr_wait_end nop subi r3, r3, 1 b plprcr_wait plprcr_wait_end: /* unlock instruction cache but leave it enabled */ lis r4, CACHE_CMD_UNLOCK_ALL@h ori r4, r4, CACHE_CMD_UNLOCK_ALL@l mtspr IC_CST, r4 isync mtspr LR, r10 /* restore original Link Register value */ blr plprcr_end: