Home | History | Annotate | Line # | Download | only in arm
      1 /*	$NetBSD: cpufunc_asm_xscale.S,v 1.25 2022/10/20 06:58:38 skrll Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
      5  * All rights reserved.
      6  *
      7  * Written by Allen Briggs and Jason R. Thorpe for Wasabi Systems, Inc.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *	This product includes software developed for the NetBSD Project by
     20  *	Wasabi Systems, Inc.
     21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     22  *    or promote products derived from this software without specific prior
     23  *    written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 
     38 /*
     39  * Copyright (c) 2001 Matt Thomas.
     40  * Copyright (c) 1997,1998 Mark Brinicombe.
     41  * Copyright (c) 1997 Causality Limited
     42  * All rights reserved.
     43  *
     44  * Redistribution and use in source and binary forms, with or without
     45  * modification, are permitted provided that the following conditions
     46  * are met:
     47  * 1. Redistributions of source code must retain the above copyright
     48  *    notice, this list of conditions and the following disclaimer.
     49  * 2. Redistributions in binary form must reproduce the above copyright
     50  *    notice, this list of conditions and the following disclaimer in the
     51  *    documentation and/or other materials provided with the distribution.
     52  * 3. All advertising materials mentioning features or use of this software
     53  *    must display the following acknowledgement:
     54  *	This product includes software developed by Causality Limited.
     55  * 4. The name of Causality Limited may not be used to endorse or promote
     56  *    products derived from this software without specific prior written
     57  *    permission.
     58  *
     59  * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
     60  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     61  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     62  * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
     63  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     64  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     65  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     69  * SUCH DAMAGE.
     70  *
     71  * XScale assembly functions for CPU / MMU / TLB specific operations
     72  */
     73 
     74 #include "assym.h"
     75 #include <arm/asm.h>
     76 #include <arm/locore.h>
     77 
     78 /*
     79  * Size of the XScale core D-cache.
     80  */
     81 #define	XSCALE_DCACHE_SIZE		0x00008000
     82 
     83 .Lblock_userspace_access:
     84 	.word	_C_LABEL(block_userspace_access)
     85 
     86 /*
     87  * CPWAIT -- Canonical method to wait for CP15 update.
     88  * From: Intel 80200 manual, section 2.3.3.
     89  *
     90  * NOTE: Clobbers the specified temp reg.
     91  */
     92 #define	CPWAIT_BRANCH							 \
     93 	sub	pc, pc, #4
     94 
     95 #define	CPWAIT(tmp)							 \
     96 	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
     97 	mov	tmp, tmp		/* wait for it to complete */	;\
     98 	CPWAIT_BRANCH			/* branch to next insn */
     99 
    100 #define	CPWAIT_AND_RETURN_SHIFTER	lsr #32
    101 
    102 #define	CPWAIT_AND_RETURN(tmp)						 \
    103 	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
    104 	/* Wait for it to complete and branch to the return address */	 \
    105 	sub	pc, lr, tmp, CPWAIT_AND_RETURN_SHIFTER
    106 
    107 ENTRY(xscale_cpwait)
    108 	CPWAIT_AND_RETURN(r0)
    109 END(xscale_cpwait)
    110 
    111 /*
    112  * We need a separate cpu_control() entry point, since we have to
    113  * invalidate the Branch Target Buffer in the event the BPRD bit
    114  * changes in the control register.
    115  */
    116 ENTRY(xscale_control)
    117 	mrc	p15, 0, r3, c1, c0, 0	/* Read the control register */
    118 	bic	r2, r3, r0		/* Clear bits */
    119 	eor	r2, r2, r1		/* XOR bits */
    120 
    121 	teq	r2, r3			/* Only write if there was a change */
    122 	mcrne	p15, 0, r0, c7, c5, 6	/* Invalidate the BTB */
    123 	mcrne	p15, 0, r2, c1, c0, 0	/* Write new control register */
    124 	mov	r0, r3			/* Return old value */
    125 
    126 	CPWAIT_AND_RETURN(r1)
    127 END(xscale_control)
    128 
    129 /*
    130  * Functions to set the MMU Translation Table Base register
    131  *
    132  * We need to clean and flush the cache as it uses virtual
    133  * addresses that are about to change.
    134  */
    135 ENTRY(xscale_setttb)
    136 #ifdef CACHE_CLEAN_BLOCK_INTR
    137 	mrs	r3, cpsr
    138 	orr	r2, r3, #(I32_bit | F32_bit)
    139 	msr	cpsr_all, r2
    140 #else
    141 	ldr	r3, .Lblock_userspace_access
    142 	ldr	r2, [r3]
    143 	orr	ip, r2, #1
    144 	str	ip, [r3]
    145 #endif
    146 	cmp	r1, #0			/* flush cache/TLB? */
    147 	beq	1f			/*   nope, so don't */
    148 	stmfd	sp!, {r0-r3, lr}
    149 	bl	_C_LABEL(xscale_cache_cleanID)
    150 	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ and BTB */
    151 	mcr	p15, 0, r0, c7, c10, 4	/* drain write and fill buffer */
    152 
    153 	CPWAIT(r0)
    154 
    155 	ldmfd	sp!, {r0-r3, lr}
    156 	cmp	r0, #1
    157 
    158 1:	/* Write the TTB */
    159 	mcr	p15, 0, r0, c2, c0, 0
    160 
    161 	beq	2f			/*   nope, so don't */
    162 
    163 	/* If we have updated the TTB we must flush the TLB */
    164 	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLB */
    165 
    166 	/* The cleanID above means we only need to flush the I cache here */
    167 	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ and BTB */
    168 
    169 	CPWAIT(r0)
    170 
    171 2:
    172 #ifdef CACHE_CLEAN_BLOCK_INTR
    173 	msr	cpsr_all, r3
    174 #else
    175 	str	r2, [r3]
    176 #endif
    177 	RET
    178 END(xscale_setttb)
    179 
    180 /*
    181  * TLB functions
    182  *
    183  * Note: We don't need to worry about issuing a CPWAIT after
    184  * TLB operations, because we expect a pmap_update() to follow.
    185  */
    186 ENTRY(xscale_tlb_flushID_SE)
    187 	mcr	p15, 0, r0, c8, c6, 1	/* flush D tlb single entry */
    188 	mcr	p15, 0, r0, c8, c5, 1	/* flush I tlb single entry */
    189 #if PAGE_SIZE == 2 * L2_S_SIZE
    190 	add	r0, r0, #L2_S_SIZE
    191 	mcr	p15, 0, r0, c8, c6, 1	/* flush D tlb single entry */
    192 	mcr	p15, 0, r0, c8, c5, 1	/* flush I tlb single entry */
    193 #endif
    194 	RET
    195 END(xscale_tlb_flushID_SE)
    196 
    197 /*
    198  * Cache functions
    199  */
    200 ENTRY(xscale_cache_flushID)
    201 	mcr	p15, 0, r0, c7, c7, 0	/* flush I+D cache */
    202 	CPWAIT_AND_RETURN(r0)
    203 END(xscale_cache_flushID)
    204 
    205 ENTRY(xscale_cache_flushI)
    206 	mcr	p15, 0, r0, c7, c5, 0	/* flush I cache */
    207 	CPWAIT_AND_RETURN(r0)
    208 END(xscale_cache_flushI)
    209 
    210 ENTRY(xscale_cache_flushD)
    211 	mcr	p15, 0, r0, c7, c6, 0	/* flush D cache */
    212 	CPWAIT_AND_RETURN(r0)
    213 END(xscale_cache_flushD)
    214 
    215 ENTRY(xscale_cache_flushI_SE)
    216 	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
    217 	CPWAIT_AND_RETURN(r0)
    218 END(xscale_cache_flushI_SE)
    219 
    220 ENTRY(xscale_cache_flushD_SE)
    221 	/*
    222 	 * Errata (rev < 2): Must clean-dcache-line to an address
    223 	 * before invalidate-dcache-line to an address, or dirty
    224 	 * bits will not be cleared in the dcache array.
    225 	 */
    226 	mcr	p15, 0, r0, c7, c10, 1
    227 	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
    228 	CPWAIT_AND_RETURN(r0)
    229 END(xscale_cache_flushD_SE)
    230 
    231 ENTRY(xscale_cache_cleanD_E)
    232 	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
    233 	CPWAIT_AND_RETURN(r0)
    234 END(xscale_cache_cleanD_E)
    235 
    236 /*
    237  * Information for the XScale cache clean/purge functions:
    238  *
    239  *	* Virtual address of the memory region to use
    240  *	* Size of memory region
    241  *
    242  * Note the virtual address for the Data cache clean operation
    243  * does not need to be backed by physical memory, since no loads
    244  * will actually be performed by the allocate-line operation.
    245  *
    246  * Note that the Mini-Data cache MUST be cleaned by executing
    247  * loads from memory mapped into a region reserved exclusively
    248  * for cleaning of the Mini-Data cache.
    249  */
    250 	.data
    251 
    252 	.global	_C_LABEL(xscale_cache_clean_addr)
    253 _C_LABEL(xscale_cache_clean_addr):
    254 	.word	0x00000000
    255 
    256 	.global	_C_LABEL(xscale_cache_clean_size)
    257 _C_LABEL(xscale_cache_clean_size):
    258 	.word	XSCALE_DCACHE_SIZE
    259 
    260 	.global	_C_LABEL(xscale_minidata_clean_addr)
    261 _C_LABEL(xscale_minidata_clean_addr):
    262 	.word	0x00000000
    263 
    264 	.global	_C_LABEL(xscale_minidata_clean_size)
    265 _C_LABEL(xscale_minidata_clean_size):
    266 	.word	0x00000800
    267 
    268 	.text
    269 
    270 .Lxscale_cache_clean_addr:
    271 	.word	_C_LABEL(xscale_cache_clean_addr)
    272 .Lxscale_cache_clean_size:
    273 	.word	_C_LABEL(xscale_cache_clean_size)
    274 
    275 .Lxscale_minidata_clean_addr:
    276 	.word	_C_LABEL(xscale_minidata_clean_addr)
    277 .Lxscale_minidata_clean_size:
    278 	.word	_C_LABEL(xscale_minidata_clean_size)
    279 
    280 #ifdef CACHE_CLEAN_BLOCK_INTR
    281 #define	XSCALE_CACHE_CLEAN_BLOCK					\
    282 	mrs	r3, cpsr					;	\
    283 	orr	r0, r3, #(I32_bit | F32_bit)			;	\
    284 	msr	cpsr_all, r0
    285 
    286 #define	XSCALE_CACHE_CLEAN_UNBLOCK					\
    287 	msr	cpsr_all, r3
    288 #else
    289 #define	XSCALE_CACHE_CLEAN_BLOCK					\
    290 	ldr	r3, .Lblock_userspace_access			;	\
    291 	ldr	ip, [r3]					;	\
    292 	orr	r0, ip, #1					;	\
    293 	str	r0, [r3]
    294 
    295 #define	XSCALE_CACHE_CLEAN_UNBLOCK					\
    296 	str	ip, [r3]
    297 #endif /* CACHE_CLEAN_BLOCK_INTR */
    298 
    299 #define	XSCALE_CACHE_CLEAN_PROLOGUE					\
    300 	XSCALE_CACHE_CLEAN_BLOCK				;	\
    301 	ldr	r2, .Lxscale_cache_clean_addr			;	\
    302 	ldmia	r2, {r0, r1}					;	\
    303 	/*								\
    304 	 * BUG ALERT!							\
    305 	 *								\
    306 	 * The XScale core has a strange cache eviction bug, which	\
    307 	 * requires us to use 2x the cache size for the cache clean	\
    308 	 * and for that area to be aligned to 2 * cache size.		\
    309 	 *								\
    310 	 * The work-around is to use 2 areas for cache clean, and to	\
    311 	 * alternate between them whenever this is done.  No one knows	\
    312 	 * why the work-around works (mmm!).				\
    313 	 */								\
    314 	eor	r0, r0, #(XSCALE_DCACHE_SIZE)			;	\
    315 	str	r0, [r2]					;	\
    316 	add	r0, r0, r1
    317 
    318 #define	XSCALE_CACHE_CLEAN_EPILOGUE					\
    319 	XSCALE_CACHE_CLEAN_UNBLOCK
    320 
    321 ENTRY_NP(xscale_cache_syncI)
    322 ENTRY_NP(xscale_cache_purgeID)
    323 	mcr	p15, 0, r0, c7, c5, 0	/* flush I cache (D cleaned below) */
    324 ENTRY_NP(xscale_cache_cleanID)
    325 ENTRY_NP(xscale_cache_purgeD)
    326 ENTRY(xscale_cache_cleanD)
    327 	XSCALE_CACHE_CLEAN_PROLOGUE
    328 
    329 1:	subs	r0, r0, #32
    330 	mcr	p15, 0, r0, c7, c2, 5	/* allocate cache line */
    331 	subs	r1, r1, #32
    332 	bne	1b
    333 
    334 	CPWAIT(r0)
    335 
    336 	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
    337 
    338 	CPWAIT(r0)
    339 
    340 	XSCALE_CACHE_CLEAN_EPILOGUE
    341 	RET
    342 END(xscale_cache_cleanD)
    343 END(xscale_cache_purgeD)
    344 END(xscale_cache_cleanID)
    345 END(xscale_cache_purgeID)
    346 END(xscale_cache_syncI)
    347 
    348 /*
    349  * Clean the mini-data cache.
    350  *
    351  * It's expected that we only use the mini-data cache for
    352  * kernel addresses, so there is no need to purge it on
    353  * context switch, and no need to prevent userspace access
    354  * while we clean it.
    355  */
    356 ENTRY(xscale_cache_clean_minidata)
    357 	ldr	r2, .Lxscale_minidata_clean_addr
    358 	ldmia	r2, {r0, r1}
    359 1:	ldr	r3, [r0], #32
    360 	subs	r1, r1, #32
    361 	bne	1b
    362 
    363 	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
    364 
    365 	CPWAIT_AND_RETURN(r1)
    366 END(xscale_cache_clean_minidata)
    367 
    368 ENTRY(xscale_cache_purgeID_E)
    369 	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
    370 	CPWAIT(r1)
    371 	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
    372 	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
    373 	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
    374 	CPWAIT_AND_RETURN(r1)
    375 END(xscale_cache_purgeID_E)
    376 
    377 ENTRY(xscale_cache_purgeD_E)
    378 	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
    379 	CPWAIT(r1)
    380 	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
    381 	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
    382 	CPWAIT_AND_RETURN(r1)
    383 END(xscale_cache_purgeD_E)
    384 
    385 /*
    386  * Soft functions
    387  */
    388 /* xscale_cache_syncI is identical to xscale_cache_purgeID */
    389 
    390 ENTRY(xscale_cache_cleanID_rng)
    391 ENTRY(xscale_cache_cleanD_rng)
    392 	cmp	r1, #0x4000
    393 	bcs	_C_LABEL(xscale_cache_cleanID)
    394 
    395 	and	r2, r0, #0x1f
    396 	add	r1, r1, r2
    397 	bic	r0, r0, #0x1f
    398 
    399 1:	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
    400 	add	r0, r0, #32
    401 	subs	r1, r1, #32
    402 	bhi	1b
    403 
    404 	CPWAIT(r0)
    405 
    406 	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
    407 
    408 	CPWAIT_AND_RETURN(r0)
    409 END(xscale_cache_cleanD_rng)
    410 END(xscale_cache_cleanID_rng)
    411 
    412 ENTRY(xscale_cache_purgeID_rng)
    413 	cmp	r1, #0x4000
    414 	bcs	_C_LABEL(xscale_cache_purgeID)
    415 
    416 	and	r2, r0, #0x1f
    417 	add	r1, r1, r2
    418 	bic	r0, r0, #0x1f
    419 
    420 1:	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
    421 	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
    422 	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
    423 	add	r0, r0, #32
    424 	subs	r1, r1, #32
    425 	bhi	1b
    426 
    427 	CPWAIT(r0)
    428 
    429 	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
    430 
    431 	CPWAIT_AND_RETURN(r0)
    432 END(xscale_cache_purgeID_rng)
    433 
    434 ENTRY(xscale_cache_purgeD_rng)
    435 	cmp	r1, #0x4000
    436 	bcs	_C_LABEL(xscale_cache_purgeD)
    437 
    438 	and	r2, r0, #0x1f
    439 	add	r1, r1, r2
    440 	bic	r0, r0, #0x1f
    441 
    442 1:	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
    443 	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
    444 	add	r0, r0, #32
    445 	subs	r1, r1, #32
    446 	bhi	1b
    447 
    448 	CPWAIT(r0)
    449 
    450 	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
    451 
    452 	CPWAIT_AND_RETURN(r0)
    453 END(xscale_cache_purgeD_rng)
    454 
    455 ENTRY(xscale_cache_syncI_rng)
    456 	cmp	r1, #0x4000
    457 	bcs	_C_LABEL(xscale_cache_syncI)
    458 
    459 	and	r2, r0, #0x1f
    460 	add	r1, r1, r2
    461 	bic	r0, r0, #0x1f
    462 
    463 1:	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
    464 	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
    465 	add	r0, r0, #32
    466 	subs	r1, r1, #32
    467 	bhi	1b
    468 
    469 	CPWAIT(r0)
    470 
    471 	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
    472 
    473 	CPWAIT_AND_RETURN(r0)
    474 END(xscale_cache_syncI_rng)
    475 
    476 ENTRY(xscale_cache_flushD_rng)
    477 	and	r2, r0, #0x1f
    478 	add	r1, r1, r2
    479 	bic	r0, r0, #0x1f
    480 
    481 1:	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
    482 	add	r0, r0, #32
    483 	subs	r1, r1, #32
    484 	bhi	1b
    485 
    486 	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
    487 
    488 	CPWAIT_AND_RETURN(r0)
    489 END(xscale_cache_flushD_rng)
    490 
    491 /*
    492  * Context switch.
    493  *
    494  * These are the CPU-specific parts of the context switcher cpu_switch()
    495  * These functions actually perform the TTB reload.
    496  */
    497 ENTRY(xscale_context_switch)
    498 	/*
    499 	 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
    500 	 * Thus the data cache will contain only kernel data and the
    501 	 * instruction cache will contain only kernel code, and all
    502 	 * kernel mappings are shared by all processes.
    503 	 */
    504 
    505 	/* Write the TTB */
    506 	mcr	p15, 0, r0, c2, c0, 0
    507 
    508 	/* If we have updated the TTB we must flush the TLB */
    509 	mcr	p15, 0, r0, c8, c7, 0	/* flush the I+D tlb */
    510 
    511 	CPWAIT_AND_RETURN(r0)
    512 END(xscale_context_switch)
    513 
    514 /*
    515  * xscale_cpu_sleep
    516  *
    517  * This is called when there is nothing on any of the run queues.
    518  * We go into IDLE mode so that any IRQ or FIQ will awaken us.
    519  *
    520  * If this is called with anything other than ARM_SLEEP_MODE_IDLE,
    521  * ignore it.
    522  */
    523 ENTRY(xscale_cpu_sleep)
    524 	tst	r0, #0x00000000
    525 	RETc(ne)
    526 	mov	r0, #0x1
    527 	mcr	p14, 0, r0, c7, c0, 0
    528 	RET
    529 END(xscale_cpu_sleep)
    530