cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sleep.S (9335B)


      1/*
      2 * linux/arch/arm/mach-omap1/sleep.S
      3 *
      4 * Low-level OMAP7XX/1510/1610 sleep/wakeUp support
      5 *
      6 * Initial SA1110 code:
      7 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
      8 *
      9 * Adapted for PXA by Nicolas Pitre:
     10 * Copyright (c) 2002 Monta Vista Software, Inc.
     11 *
     12 * Support for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
     13 *
     14 * This program is free software; you can redistribute it and/or modify it
     15 * under the terms of the GNU General Public License as published by the
     16 * Free Software Foundation; either version 2 of the License, or (at your
     17 * option) any later version.
     18 *
     19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
     20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
     22 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
     25 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 *
     30 * You should have received a copy of the GNU General Public License along
     31 * with this program; if not, write to the Free Software Foundation, Inc.,
     32 * 675 Mass Ave, Cambridge, MA 02139, USA.
     33 */
     34
     35#include <linux/linkage.h>
     36
     37#include <asm/assembler.h>
     38
     39#include "hardware.h"
     40
     41#include "iomap.h"
     42#include "pm.h"
     43
     44		.text
     45
     46
     47/*
     48 * Forces OMAP into deep sleep state
     49 *
     50 * omapXXXX_cpu_suspend()
     51 *
     52 * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed
     53 * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1
     54 * in register r1.
     55 *
     56 * Note: This code get's copied to internal SRAM at boot. When the OMAP
     57 *	 wakes up it continues execution at the point it went to sleep.
     58 *
     59 * Note: Because of errata work arounds we have processor specific functions
     60 *       here. They are mostly the same, but slightly different.
     61 *
     62 */
     63
     64#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
     65	.align	3
     66ENTRY(omap7xx_cpu_suspend)
     67
     68	@ save registers on stack
     69	stmfd	sp!, {r0 - r12, lr}
     70
     71	@ Drain write cache
     72	mov	r4, #0
     73	mcr	p15, 0, r0, c7, c10, 4
     74	nop
     75
     76	@ load base address of Traffic Controller
     77	mov	r6, #TCMIF_ASM_BASE & 0xff000000
     78	orr	r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
     79	orr	r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
     80
     81	@ prepare to put SDRAM into self-refresh manually
     82	ldr	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
     83	orr	r9, r7, #SELF_REFRESH_MODE & 0xff000000
     84	orr	r9, r9, #SELF_REFRESH_MODE & 0x000000ff
     85	str	r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
     86
     87	@ prepare to put EMIFS to Sleep
     88	ldr	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
     89	orr	r9, r8, #IDLE_EMIFS_REQUEST & 0xff
     90	str	r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
     91
     92	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
     93	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
     94	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
     95	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
     96
     97	@ turn off clock domains
     98	@ do not disable PERCK (0x04)
     99	mov	r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff
    100	orr	r5, r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff00
    101	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
    102
    103	@ request ARM idle
    104	mov	r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff
    105	orr	r3, r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff00
    106	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
    107
    108	@ disable instruction cache
    109	mrc	p15, 0, r9, c1, c0, 0
    110	bic	r2, r9, #0x1000
    111	mcr	p15, 0, r2, c1, c0, 0
    112	nop
    113
    114/*
    115 * Let's wait for the next wake up event to wake us up. r0 can't be
    116 * used here because r0 holds ARM_IDLECT1
    117 */
    118	mov	r2, #0
    119	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
    120/*
    121 * omap7xx_cpu_suspend()'s resume point.
    122 *
    123 * It will just start executing here, so we'll restore stuff from the
    124 * stack.
    125 */
    126	@ re-enable Icache
    127	mcr	p15, 0, r9, c1, c0, 0
    128
    129	@ reset the ARM_IDLECT1 and ARM_IDLECT2.
    130	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
    131	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
    132
    133	@ Restore EMIFF controls
    134	str	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
    135	str	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
    136
    137	@ restore regs and return
    138	ldmfd	sp!, {r0 - r12, pc}
    139
    140ENTRY(omap7xx_cpu_suspend_sz)
    141	.word	. - omap7xx_cpu_suspend
    142#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
    143
    144#ifdef CONFIG_ARCH_OMAP15XX
    145	.align	3
    146ENTRY(omap1510_cpu_suspend)
    147
    148	@ save registers on stack
    149	stmfd	sp!, {r0 - r12, lr}
    150
    151	@ load base address of Traffic Controller
    152	mov	r4, #TCMIF_ASM_BASE & 0xff000000
    153	orr	r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
    154	orr	r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
    155
    156	@ work around errata of OMAP1510 PDE bit for TC shut down
    157	@ clear PDE bit
    158	ldr	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
    159	bic	r5, r5, #PDE_BIT & 0xff
    160	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
    161
    162	@ set PWD_EN bit
    163	and	r5, r5, #PWD_EN_BIT & 0xff
    164	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
    165
    166	@ prepare to put SDRAM into self-refresh manually
    167	ldr	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
    168	orr	r5, r5, #SELF_REFRESH_MODE & 0xff000000
    169	orr	r5, r5, #SELF_REFRESH_MODE & 0x000000ff
    170	str	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
    171
    172	@ prepare to put EMIFS to Sleep
    173	ldr	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
    174	orr	r5, r5, #IDLE_EMIFS_REQUEST & 0xff
    175	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
    176
    177	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
    178	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
    179	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
    180	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
    181
    182	@ turn off clock domains
    183	mov	r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
    184	orr	r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
    185	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
    186
    187	@ request ARM idle
    188	mov	r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff
    189	orr	r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00
    190	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
    191
    192	mov	r5, #IDLE_WAIT_CYCLES & 0xff
    193	orr	r5, r5, #IDLE_WAIT_CYCLES & 0xff00
    194l_1510_2:
    195	subs	r5, r5, #1
    196	bne	l_1510_2
    197/*
    198 * Let's wait for the next wake up event to wake us up. r0 can't be
    199 * used here because r0 holds ARM_IDLECT1
    200 */
    201	mov	r2, #0
    202	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
    203/*
    204 * omap1510_cpu_suspend()'s resume point.
    205 *
    206 * It will just start executing here, so we'll restore stuff from the
    207 * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
    208 */
    209	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
    210	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
    211
    212	@ restore regs and return
    213	ldmfd	sp!, {r0 - r12, pc}
    214
    215ENTRY(omap1510_cpu_suspend_sz)
    216	.word	. - omap1510_cpu_suspend
    217#endif /* CONFIG_ARCH_OMAP15XX */
    218
    219#if defined(CONFIG_ARCH_OMAP16XX)
    220	.align	3
    221ENTRY(omap1610_cpu_suspend)
    222
    223	@ save registers on stack
    224	stmfd	sp!, {r0 - r12, lr}
    225
    226	@ Drain write cache
    227	mov	r4, #0
    228	mcr	p15, 0, r0, c7, c10, 4
    229	nop
    230
    231	@ Load base address of Traffic Controller
    232	mov	r6, #TCMIF_ASM_BASE & 0xff000000
    233	orr	r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
    234	orr	r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
    235
    236	@ Prepare to put SDRAM into self-refresh manually
    237	ldr	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
    238	orr	r9, r7, #SELF_REFRESH_MODE & 0xff000000
    239	orr	r9, r9, #SELF_REFRESH_MODE & 0x000000ff
    240	str	r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
    241
    242	@ Prepare to put EMIFS to Sleep
    243	ldr	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
    244	orr	r9, r8, #IDLE_EMIFS_REQUEST & 0xff
    245	str	r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
    246
    247	@ Load base address of ARM_IDLECT1 and ARM_IDLECT2
    248	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
    249	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
    250	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
    251
    252	@ Turn off clock domains
    253	@ Do not disable PERCK (0x04)
    254	mov	r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
    255	orr	r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
    256	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
    257
    258	@ Request ARM idle
    259	mov	r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
    260	orr	r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
    261	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
    262
    263/*
    264 * Let's wait for the next wake up event to wake us up. r0 can't be
    265 * used here because r0 holds ARM_IDLECT1
    266 */
    267	mov	r2, #0
    268	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
    269
    270	@ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions
    271	@ according to this formula:
    272	@ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV
    273	@ Max DPLL_MULT = 18
    274	@ DPLL_DIV = 1
    275	@ ARMDIV = 1
    276	@ => 74 nop-instructions
    277	nop
    278	nop
    279	nop
    280	nop
    281	nop
    282	nop
    283	nop
    284	nop
    285	nop
    286	nop	@10
    287	nop
    288	nop
    289	nop
    290	nop
    291	nop
    292	nop
    293	nop
    294	nop
    295	nop
    296	nop	@20
    297	nop
    298	nop
    299	nop
    300	nop
    301	nop
    302	nop
    303	nop
    304	nop
    305	nop
    306	nop	@30
    307	nop
    308	nop
    309	nop
    310	nop
    311	nop
    312	nop
    313	nop
    314	nop
    315	nop
    316	nop	@40
    317	nop
    318	nop
    319	nop
    320	nop
    321	nop
    322	nop
    323	nop
    324	nop
    325	nop
    326	nop	@50
    327	nop
    328	nop
    329	nop
    330	nop
    331	nop
    332	nop
    333	nop
    334	nop
    335	nop
    336	nop	@60
    337	nop
    338	nop
    339	nop
    340	nop
    341	nop
    342	nop
    343	nop
    344	nop
    345	nop
    346	nop	@70
    347	nop
    348	nop
    349	nop
    350	nop	@74
    351/*
    352 * omap1610_cpu_suspend()'s resume point.
    353 *
    354 * It will just start executing here, so we'll restore stuff from the
    355 * stack.
    356 */
    357	@ Restore the ARM_IDLECT1 and ARM_IDLECT2.
    358	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
    359	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
    360
    361	@ Restore EMIFF controls
    362	str	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
    363	str	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
    364
    365	@ Restore regs and return
    366	ldmfd	sp!, {r0 - r12, pc}
    367
    368ENTRY(omap1610_cpu_suspend_sz)
    369	.word	. - omap1610_cpu_suspend
    370#endif /* CONFIG_ARCH_OMAP16XX */