Home | History | Annotate | Line # | Download | only in arm
      1 /*-
      2  * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
      3  * All rights reserved.
      4  *
      5  * Developed by Semihalf.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of MARVELL nor the names of contributors
     16  *    may be used to endorse or promote products derived from this software
     17  *    without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 #include "assym.h"
     33 #include <arm/asm.h>
     34 #include <arm/locore.h>
     35 
     36 .Lsheeva_cache_line_size:
     37 	.word	_C_LABEL(arm_pcache) + DCACHE_LINE_SIZE
     38 .Lsheeva_asm_page_mask:
     39 	.word	_C_LABEL(PAGE_MASK)
     40 
     41 ENTRY(sheeva_dcache_wbinv_range)
     42 	push	{r4,r5}
     43 	mrs	r4, cpsr
     44 	orr	r5, r4, #I32_bit | F32_bit
     45 
     46 	/* Start with cache line aligned address */
     47 	ldr	ip, .Lsheeva_cache_line_size
     48 	ldr	r3, [ip]
     49 	sub	r3, r3, #1
     50 	and	r2, r0, r3
     51 	add	r1, r1, r2
     52 	add	r1, r1, r3
     53 	bic	r1, r1, r3
     54 	bic	r0, r0, r3
     55 
     56 	ldr	ip, .Lsheeva_asm_page_mask
     57 	and	r2, r0, ip
     58 	rsb	r2, r2, #PAGE_SIZE
     59 	cmp	r1, r2
     60 	movcc	ip, r1
     61 	movcs	ip, r2
     62 	sub	r2, r0, #1
     63 1:
     64 	add	r2, r2, ip
     65 	msr	cpsr_c, r5		/* Disable irqs */
     66 	mcr	p15, 5, r0, c15, c15, 0	/* Clean and inv zone start address */
     67 	mcr	p15, 5, r2, c15, c15, 1	/* Clean and inv zone end address */
     68 	msr	cpsr_c, r4		/* Enable irqs */
     69 
     70 	add	r0, r0, ip
     71 	sub	r1, r1, ip
     72 	cmp	r1, #PAGE_SIZE
     73 	movcc	ip, r1
     74 	movcs	ip, #PAGE_SIZE
     75 	cmp	r1, #0
     76 	bne	1b
     77 	mov	r0, #0
     78 	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
     79 	pop	{r4, r5}
     80 	RET
     81 END(sheeva_dcache_wbinv_range)
     82 
     83 ENTRY(sheeva_dcache_inv_range)
     84 	push	{r4,r5}
     85 	mrs	r4, cpsr
     86 	orr	r5, r4, #I32_bit | F32_bit
     87 
     88 	/* Start with cache line aligned address */
     89 	ldr	ip, .Lsheeva_cache_line_size
     90 	ldr	r3, [ip]
     91 	sub	r3, r3, #1
     92 	and	r2, r0, r3
     93 	add	r1, r1, r2
     94 	add	r1, r1, r3
     95 	bic	r1, r1, r3
     96 	bic	r0, r0, r3
     97 
     98 	ldr	ip, .Lsheeva_asm_page_mask
     99 	and	r2, r0, ip
    100 	rsb	r2, r2, #PAGE_SIZE
    101 	cmp	r1, r2
    102 	movcc	ip, r1
    103 	movcs	ip, r2
    104 	sub	r2, r0, #1
    105 1:
    106 	add	r2, r2, ip
    107 	msr	cpsr_c, r5		/* Disable irqs */
    108 	mcr	p15, 5, r0, c15, c14, 0	/* Inv zone start address */
    109 	mcr	p15, 5, r2, c15, c14, 1	/* Inv zone end address */
    110 	msr	cpsr_c, r4		/* Enable irqs */
    111 
    112 	add	r0, r0, ip
    113 	sub	r1, r1, ip
    114 	cmp	r1, #PAGE_SIZE
    115 	movcc	ip, r1
    116 	movcs	ip, #PAGE_SIZE
    117 	cmp	r1, #0
    118 	bne	1b
    119 	mov	r0, #0
    120 	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
    121 	pop	{r4, r5}
    122 	RET
    123 END(sheeva_dcache_inv_range)
    124 
    125 ENTRY(sheeva_dcache_wb_range)
    126 	push	{r4,r5}
    127 	mrs	r4, cpsr
    128 	orr	r5, r4, #I32_bit | F32_bit
    129 
    130 	/* Start with cache line aligned address */
    131 	ldr	ip, .Lsheeva_cache_line_size
    132 	ldr	r3, [ip]
    133 	sub	r3, r3, #1
    134 	and	r2, r0, r3
    135 	add	r1, r1, r2
    136 	add	r1, r1, r3
    137 	bic	r1, r1, r3
    138 	bic	r0, r0, r3
    139 
    140 	ldr	ip, .Lsheeva_asm_page_mask
    141 	and	r2, r0, ip
    142 	rsb	r2, r2, #PAGE_SIZE
    143 	cmp	r1, r2
    144 	movcc	ip, r1
    145 	movcs	ip, r2
    146 	sub	r2, r0, #1
    147 1:
    148 	add	r2, r2, ip
    149 	msr	cpsr_c, r5		/* Disable irqs */
    150 	mcr	p15, 5, r0, c15, c13, 0	/* Clean zone start address */
    151 	mcr	p15, 5, r2, c15, c13, 1	/* Clean zone end address */
    152 	msr	cpsr_c, r4		/* Enable irqs */
    153 
    154 	add	r0, r0, ip
    155 	sub	r1, r1, ip
    156 	cmp	r1, #PAGE_SIZE
    157 	movcc	ip, r1
    158 	movcs	ip, #PAGE_SIZE
    159 	cmp	r1, #0
    160 	bne	1b
    161 	mov	r0, #0
    162 	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
    163 	pop	{r4, r5}
    164 	RET
    165 END(sheeva_dcache_wb_range)
    166 
    167 ENTRY(sheeva_idcache_wbinv_range)
    168 	push	{r4,r5}
    169 	mrs	r4, cpsr
    170 	orr	r5, r4, #I32_bit | F32_bit
    171 
    172 	/* Start with cache line aligned address */
    173 	ldr	ip, .Lsheeva_cache_line_size
    174 	ldr	r3, [ip]
    175 	sub	r3, r3, #1
    176 	and	r2, r0, r3
    177 	add	r1, r1, r2
    178 	add	r1, r1, r3
    179 	bic	r1, r1, r3
    180 	bic	r0, r0, r3
    181 
    182 	ldr	ip, .Lsheeva_asm_page_mask
    183 	and	r2, r0, ip
    184 	rsb	r2, r2, #PAGE_SIZE
    185 	cmp	r1, r2
    186 	movcc	ip, r1
    187 	movcs	ip, r2
    188 	sub	r2, r0, #1
    189 1:
    190 	add	r2, r2, ip
    191 	msr	cpsr_c, r5		/* Disable irqs */
    192 	mcr	p15, 5, r0, c15, c15, 0	/* Clean and inv zone start address */
    193 	mcr	p15, 5, r2, c15, c15, 1	/* Clean and inv zone end address */
    194 	msr	cpsr_c, r4		/* Enable irqs */
    195 
    196 	/* Invalidate and clean icache line by line */
    197 2:
    198 	mcr	p15, 0, r0, c7, c5, 1
    199 	add	r0, r0, r3
    200 	cmp	r2, r0
    201 	bhi	2b
    202 
    203 	add	r0, r0, ip
    204 	sub	r1, r1, ip
    205 	cmp	r1, #PAGE_SIZE
    206 	movcc	ip, r1
    207 	movcs	ip, #PAGE_SIZE
    208 	cmp	r1, #0
    209 	bne	1b
    210 	mov	r0, #0
    211 	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
    212 	pop	{r4, r5}
    213 	RET
    214 END(sheeva_idcache_wbinv_range)
    215 
    216 ENTRY(sheeva_sdcache_wbinv_range)
    217 	push	{r4,r5}
    218 	mrs	r4, cpsr
    219 	orr	r5, r4, #I32_bit | F32_bit
    220 
    221 	mov	r1, r2		/* ignore paddr_t argument */
    222 
    223 	/* Start with cache line aligned address */
    224 	ldr	ip, .Lsheeva_cache_line_size
    225 	ldr	ip, [ip]
    226 	sub	ip, ip, #1
    227 	and	r2, r0, ip
    228 	add	r1, r1, r2
    229 	add	r1, r1, ip
    230 	bic	r1, r1, ip
    231 	bic	r0, r0, ip
    232 
    233 	ldr	ip, .Lsheeva_asm_page_mask
    234 	and	r2, r0, ip
    235 	rsb	r2, r2, #PAGE_SIZE
    236 	cmp	r1, r2
    237 	movcc	ip, r1
    238 	movcs	ip, r2
    239 	sub	r2, r0, #1
    240 1:
    241 	add	r2, r2, ip
    242 	msr	cpsr_c, r5		/* Disable irqs */
    243 	mcr	p15, 1, r0, c15, c9, 4	/* Clean L2 zone start address */
    244 	mcr	p15, 1, r2, c15, c9, 5	/* Clean L2 zone end address */
    245 	mcr	p15, 1, r0, c15, c11, 4	/* Inv L2 zone start address */
    246 	mcr	p15, 1, r2, c15, c11, 5	/* Inv L2 zone end address */
    247 	msr	cpsr_c, r4		/* Enable irqs */
    248 
    249 	add	r0, r0, ip
    250 	sub	r1, r1, ip
    251 	cmp	r1, #PAGE_SIZE
    252 	movcc	ip, r1
    253 	movcs	ip, #PAGE_SIZE
    254 	cmp	r1, #0
    255 	bne	1b
    256 	mov	r0, #0
    257 	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
    258 	pop	{r4, r5}
    259 	RET
    260 END(sheeva_sdcache_wbinv_range)
    261 
    262 ENTRY(sheeva_sdcache_inv_range)
    263 	push	{r4,r5}
    264 	mrs	r4, cpsr
    265 	orr	r5, r4, #I32_bit | F32_bit
    266 
    267 	mov	r1, r2		/* ignore paddr_t argument */
    268 
    269 	/* Start with cache line aligned address */
    270 	ldr	ip, .Lsheeva_cache_line_size
    271 	ldr	r3, [ip]
    272 	sub	r3, r3, #1
    273 	and	r2, r0, r3
    274 	add	r1, r1, r2
    275 	add	r1, r1, r3
    276 	bic	r1, r1, r3
    277 	bic	r0, r0, r3
    278 
    279 	ldr	ip, .Lsheeva_asm_page_mask
    280 	and	r2, r0, ip
    281 	rsb	r2, r2, #PAGE_SIZE
    282 	cmp	r1, r2
    283 	movcc	ip, r1
    284 	movcs	ip, r2
    285 	sub	r2, r2, #1
    286 1:
    287 	add	r2, r2, ip
    288 	msr	cpsr_c, r5		/* Disable irqs */
    289 	mcr	p15, 1, r0, c15, c11, 4	/* Inv L2 zone start address */
    290 	mcr	p15, 1, r2, c15, c11, 5	/* Inv L2 zone end address */
    291 	msr	cpsr_c, r4		/* Enable irqs */
    292 
    293 	add	r0, r0, ip
    294 	sub	r1, r1, ip
    295 	cmp	r1, #PAGE_SIZE
    296 	movcc	ip, r1
    297 	movcs	ip, #PAGE_SIZE
    298 	cmp	r1, #0
    299 	bne	1b
    300 	mov	r0, #0
    301 	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
    302 	pop	{r4, r5}
    303 	RET
    304 END(sheeva_sdcache_inv_range)
    305 
    306 ENTRY(sheeva_sdcache_wb_range)
    307 	push	{r4,r5}
    308 	mrs	r4, cpsr
    309 	orr	r5, r4, #I32_bit | F32_bit
    310 
    311 	mov	r1, r2		/* ignore paddr_t argument */
    312 
    313 	/* Start with cache line aligned address */
    314 	ldr	ip, .Lsheeva_cache_line_size
    315 	ldr	r3, [ip]
    316 	sub	r3, r3, #1
    317 	and	r2, r0, r3
    318 	add	r1, r1, r2
    319 	add	r1, r1, r3
    320 	bic	r1, r1, r3
    321 	bic	r0, r0, r3
    322 
    323 	ldr	ip, .Lsheeva_asm_page_mask
    324 	and	r2, r0,	ip
    325 	rsb	r2, r2, #PAGE_SIZE
    326 	cmp	r1, r2
    327 	movcc	ip, r1
    328 	movcs	ip, r2
    329 	sub	r2, r0, #1
    330 1:
    331 	add	r2, r2, ip
    332 	msr	cpsr_c, r5		/* Disable irqs */
    333 	mcr	p15, 1, r0, c15, c9, 4	/* Clean L2 zone start address */
    334 	mcr	p15, 1, r2, c15, c9, 5	/* Clean L2 zone end address */
    335 	msr	cpsr_c, r4		/* Enable irqs */
    336 
    337 	add	r0, r0, ip
    338 	sub	r1, r1, ip
    339 	cmp	r1, #PAGE_SIZE
    340 	movcc	ip, r1
    341 	movcs	ip, #PAGE_SIZE
    342 	cmp	r1, #0
    343 	bne	1b
    344 	mov	r0, #0
    345 	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
    346 	pop	{r4, r5}
    347 	RET
    348 END(sheeva_sdcache_wb_range)
    349 
    350 ENTRY(sheeva_sdcache_wbinv_all)
    351 	mov	r0, #0
    352 	mcr	p15, 1, r0, c15, c9, 0	/* Clean L2 */
    353 	mcr	p15, 1, r0, c15, c11, 0	/* Invalidate L2 */
    354 	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
    355 	RET
    356 END(sheeva_sdcache_wbinv_all)
    357 
    358 /*
    359  * CPU sleep
    360  */
    361 ENTRY_NP(sheeva_cpu_sleep)
    362 	mov	r0, #0
    363 	mcr	p15, 0, r0, c7, c0, 4	/* wait for interrupt */
    364 	RET
    365 END(sheeva_cpu_sleep)
    366