Home | History | Annotate | Download | only in mpc86xx
      1 #include <config.h>
      2 #include <mpc86xx.h>
      3 
      4 #include <ppc_asm.tmpl>
      5 #include <ppc_defs.h>
      6 
      7 #include <asm/cache.h>
      8 #include <asm/mmu.h>
      9 
     10 #ifndef CACHE_LINE_SIZE
     11 # define CACHE_LINE_SIZE L1_CACHE_BYTES
     12 #endif
     13 
     14 #if CACHE_LINE_SIZE == 128
     15 #define LG_CACHE_LINE_SIZE 7
     16 #elif CACHE_LINE_SIZE == 32
     17 #define LG_CACHE_LINE_SIZE 5
     18 #elif CACHE_LINE_SIZE == 16
     19 #define LG_CACHE_LINE_SIZE 4
     20 #elif CACHE_LINE_SIZE == 8
     21 #define LG_CACHE_LINE_SIZE 3
     22 #else
     23 # error "Invalid cache line size!"
     24 #endif
     25 
     26 /*
     27  * Most of this code is taken from 74xx_7xx/cache.S
     28  * and then cleaned up a bit
     29  */
     30 
     31 /*
     32  * Invalidate L1 instruction cache.
     33  */
     34 _GLOBAL(invalidate_l1_instruction_cache)
     35 	/* use invalidate-all bit in HID0 */
     36 	mfspr	r3,HID0
     37 	ori	r3,r3,HID0_ICFI
     38 	mtspr	HID0,r3
     39 	isync
     40 	blr
     41 
     42 /*
     43  * Invalidate L1 data cache.
     44  */
     45 _GLOBAL(invalidate_l1_data_cache)
     46 	mfspr	r3,HID0
     47 	ori	r3,r3,HID0_DCFI
     48 	mtspr	HID0,r3
     49 	isync
     50 	blr
     51 
     52 /*
     53  * Flush data cache.
     54  */
     55 _GLOBAL(flush_dcache)
     56 	lis	r3,0
     57 	lis	r5,CACHE_LINE_SIZE
     58 flush:
     59 	cmp	0,1,r3,r5
     60 	bge	done
     61 	lwz	r5,0(r3)
     62 	lis	r5,CACHE_LINE_SIZE
     63 	addi	r3,r3,0x4
     64 	b	flush
     65 done:
     66 	blr
     67 /*
     68  * Write any modified data cache blocks out to memory
     69  * and invalidate the corresponding instruction cache blocks.
     70  * This is a no-op on the 601.
     71  *
     72  * flush_icache_range(unsigned long start, unsigned long stop)
     73  */
     74 _GLOBAL(flush_icache_range)
     75 	li	r5,CACHE_LINE_SIZE-1
     76 	andc	r3,r3,r5
     77 	subf	r4,r3,r4
     78 	add	r4,r4,r5
     79 	srwi.	r4,r4,LG_CACHE_LINE_SIZE
     80 	beqlr
     81 	mtctr	r4
     82 	mr	r6,r3
     83 1:	dcbst	0,r3
     84 	addi	r3,r3,CACHE_LINE_SIZE
     85 	bdnz	1b
     86 	sync				/* wait for dcbst's to get to ram */
     87 	mtctr	r4
     88 2:	icbi	0,r6
     89 	addi	r6,r6,CACHE_LINE_SIZE
     90 	bdnz	2b
     91 	sync				/* additional sync needed on g4 */
     92 	isync
     93 	blr
     94 /*
     95  * Write any modified data cache blocks out to memory.
     96  * Does not invalidate the corresponding cache lines (especially for
     97  * any corresponding instruction cache).
     98  *
     99  * clean_dcache_range(unsigned long start, unsigned long stop)
    100  */
    101 _GLOBAL(clean_dcache_range)
    102 	li	r5,CACHE_LINE_SIZE-1
    103 	andc	r3,r3,r5	/* align r3 down to cache line */
    104 	subf	r4,r3,r4	/* r4 = offset of stop from start of cache line */
    105 	add	r4,r4,r5	/* r4 += cache_line_size-1 */
    106 	srwi.	r4,r4,LG_CACHE_LINE_SIZE  /* r4 = number of cache lines to flush */
    107 	beqlr				  /* if r4 == 0 return */
    108 	mtctr	r4			  /* ctr = r4 */
    109 
    110 	sync
    111 1:	dcbst	0,r3
    112 	addi	r3,r3,CACHE_LINE_SIZE
    113 	bdnz	1b
    114 	sync				/* wait for dcbst's to get to ram */
    115 	blr
    116 
    117 /*
    118  * Flush a particular page from the data cache to RAM.
    119  * Note: this is necessary because the instruction cache does *not*
    120  * snoop from the data cache.
    121  *
    122  *	void __flush_page_to_ram(void *page)
    123  */
    124 _GLOBAL(__flush_page_to_ram)
    125 	rlwinm	r3,r3,0,0,19		/* Get page base address */
    126 	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */
    127 	mtctr	r4
    128 	mr	r6,r3
    129 0:	dcbst	0,r3			/* Write line to ram */
    130 	addi	r3,r3,CACHE_LINE_SIZE
    131 	bdnz	0b
    132 	sync
    133 	mtctr	r4
    134 1:	icbi	0,r6
    135 	addi	r6,r6,CACHE_LINE_SIZE
    136 	bdnz	1b
    137 	sync
    138 	isync
    139 	blr
    140 
    141 /*
    142  * Flush a particular page from the instruction cache.
    143  * Note: this is necessary because the instruction cache does *not*
    144  * snoop from the data cache.
    145  *
    146  *	void __flush_icache_page(void *page)
    147  */
    148 _GLOBAL(__flush_icache_page)
    149 	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */
    150 	mtctr	r4
    151 1:	icbi	0,r3
    152 	addi	r3,r3,CACHE_LINE_SIZE
    153 	bdnz	1b
    154 	sync
    155 	isync
    156 	blr
    157 
    158 /*
    159  * Clear a page using the dcbz instruction, which doesn't cause any
    160  * memory traffic (except to write out any cache lines which get
    161  * displaced).  This only works on cacheable memory.
    162  */
    163 _GLOBAL(clear_page)
    164 	li	r0,4096/CACHE_LINE_SIZE
    165 	mtctr	r0
    166 1:	dcbz	0,r3
    167 	addi	r3,r3,CACHE_LINE_SIZE
    168 	bdnz	1b
    169 	blr
    170 
    171 /*
    172  * Enable L1 Instruction cache
    173  */
    174 _GLOBAL(icache_enable)
    175 	mfspr	r3, HID0
    176 	li	r5, HID0_ICFI|HID0_ILOCK
    177 	andc	r3, r3, r5
    178 	ori	r3, r3, HID0_ICE
    179 	ori	r5, r3, HID0_ICFI
    180 	mtspr	HID0, r5
    181 	mtspr	HID0, r3
    182 	isync
    183 	blr
    184 
    185 /*
    186  * Disable L1 Instruction cache
    187  */
    188 _GLOBAL(icache_disable)
    189 	mflr	r4
    190 	bl	invalidate_l1_instruction_cache		/* uses r3 */
    191 	sync
    192 	mtlr	r4
    193 	mfspr	r3, HID0
    194 	li	r5, 0
    195 	ori	r5, r5, HID0_ICE
    196 	andc	r3, r3, r5
    197 	mtspr	HID0, r3
    198 	isync
    199 	blr
    200 
    201 /*
    202  * Is instruction cache enabled?
    203  */
    204 _GLOBAL(icache_status)
    205 	mfspr	r3, HID0
    206 	andi.	r3, r3, HID0_ICE
    207 	blr
    208 
    209 
    210 _GLOBAL(l1dcache_enable)
    211 	mfspr	r3, HID0
    212 	li	r5, HID0_DCFI|HID0_DLOCK
    213 	andc	r3, r3, r5
    214 	mtspr	HID0, r3		/* no invalidate, unlock */
    215 	ori	r3, r3, HID0_DCE
    216 	ori	r5, r3, HID0_DCFI
    217 	mtspr	HID0, r5		/* enable + invalidate */
    218 	mtspr	HID0, r3		/* enable */
    219 	sync
    220 	blr
    221 
    222 /*
    223  * Enable data cache(s) - L1 and optionally L2
    224  * Calls l2cache_enable. LR saved in r5
    225  */
    226 _GLOBAL(dcache_enable)
    227 	mfspr	r3, HID0
    228 	li	r5, HID0_DCFI|HID0_DLOCK
    229 	andc	r3, r3, r5
    230 	mtspr	HID0, r3		/* no invalidate, unlock */
    231 	ori	r3, r3, HID0_DCE
    232 	ori	r5, r3, HID0_DCFI
    233 	mtspr	HID0, r5		/* enable + invalidate */
    234 	mtspr	HID0, r3		/* enable */
    235 	sync
    236 #ifdef CONFIG_SYS_L2
    237 	mflr	r5
    238 	bl	l2cache_enable		/* uses r3 and r4 */
    239 	sync
    240 	mtlr	r5
    241 #endif
    242 	blr
    243 
    244 
    245 /*
    246  * Disable data cache(s) - L1 and optionally L2
    247  * Calls flush_dcache and l2cache_disable_no_flush.
    248  * LR saved in r4
    249  */
    250 _GLOBAL(dcache_disable)
    251 	mflr	r4			/* save link register */
    252 	bl	flush_dcache	/* uses r3 and r5 */
    253 	sync
    254 	mfspr	r3, HID0
    255 	li	r5, HID0_DCFI|HID0_DLOCK
    256 	andc	r3, r3, r5
    257 	mtspr	HID0, r3		/* no invalidate, unlock */
    258 	li	r5, HID0_DCE|HID0_DCFI
    259 	andc	r3, r3, r5		/* no enable, no invalidate */
    260 	mtspr	HID0, r3
    261 	sync
    262 #ifdef CONFIG_SYS_L2
    263 	bl	l2cache_disable_no_flush /* uses r3 */
    264 #endif
    265 	mtlr	r4			/* restore link register */
    266 	blr
    267 
    268 /*
    269  * Is data cache enabled?
    270  */
    271 _GLOBAL(dcache_status)
    272 	mfspr	r3, HID0
    273 	andi.	r3, r3, HID0_DCE
    274 	blr
    275 
    276 /*
    277  * Invalidate L2 cache using L2I, assume L2 is enabled
    278  */
    279 _GLOBAL(l2cache_invalidate)
    280 	mfspr	r3, l2cr
    281 	rlwinm.	r3, r3, 0, 0, 0
    282 	beq	1f
    283 
    284 	mfspr	r3, l2cr
    285 	rlwinm	r3, r3, 0, 1, 31
    286 
    287 #ifdef	CONFIG_ALTIVEC
    288 	dssall
    289 #endif
    290 	sync
    291 	mtspr	l2cr, r3
    292 	sync
    293 1:	mfspr	r3, l2cr
    294 	oris	r3, r3, L2CR_L2I@h
    295 	mtspr	l2cr, r3
    296 
    297 invl2:
    298 	mfspr	r3, l2cr
    299 	andis.	r3, r3, L2CR_L2I@h
    300 	bne	invl2
    301 	blr
    302 
    303 /*
    304  * Enable L2 cache
    305  * Calls l2cache_invalidate. LR is saved in r4
    306  */
    307 _GLOBAL(l2cache_enable)
    308 	mflr	r4			/* save link register */
    309 	bl	l2cache_invalidate	/* uses r3 */
    310 	sync
    311 	lis	r3, L2_ENABLE@h
    312 	ori	r3, r3, L2_ENABLE@l
    313 	mtspr	l2cr, r3
    314 	isync
    315 	mtlr	r4			/* restore link register */
    316 	blr
    317 
    318 /*
    319  * Disable L2 cache
    320  * Calls flush_dcache. LR is saved in r4
    321  */
    322 _GLOBAL(l2cache_disable)
    323 	mflr	r4			/* save link register */
    324 	bl	flush_dcache		/* uses r3 and r5 */
    325 	sync
    326 	mtlr	r4			/* restore link register */
    327 l2cache_disable_no_flush:		/* provide way to disable L2 w/o flushing */
    328 	lis	r3, L2_INIT@h
    329 	ori	r3, r3, L2_INIT@l
    330 	mtspr	l2cr, r3
    331 	isync
    332 	blr
    333