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

swsusp_booke.S (3896B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Based on swsusp_32.S, modified for FSL BookE by
      4 * Anton Vorontsov <avorontsov@ru.mvista.com>
      5 * Copyright (c) 2009-2010 MontaVista Software, LLC.
      6 */
      7
      8#include <linux/threads.h>
      9#include <asm/processor.h>
     10#include <asm/page.h>
     11#include <asm/cputable.h>
     12#include <asm/thread_info.h>
     13#include <asm/ppc_asm.h>
     14#include <asm/asm-offsets.h>
     15#include <asm/mmu.h>
     16
     17/*
     18 * Structure for storing CPU registers on the save area.
     19 */
     20#define SL_SP		0
     21#define SL_PC		4
     22#define SL_MSR		8
     23#define SL_TCR		0xc
     24#define SL_SPRG0	0x10
     25#define SL_SPRG1	0x14
     26#define SL_SPRG2	0x18
     27#define SL_SPRG3	0x1c
     28#define SL_SPRG4	0x20
     29#define SL_SPRG5	0x24
     30#define SL_SPRG6	0x28
     31#define SL_SPRG7	0x2c
     32#define SL_TBU		0x30
     33#define SL_TBL		0x34
     34#define SL_R2		0x38
     35#define SL_CR		0x3c
     36#define SL_LR		0x40
     37#define SL_R12		0x44	/* r12 to r31 */
     38#define SL_SIZE		(SL_R12 + 80)
     39
     40	.section .data
     41	.align	5
     42
     43_GLOBAL(swsusp_save_area)
     44	.space	SL_SIZE
     45
     46
     47	.section .text
     48	.align	5
     49
     50_GLOBAL(swsusp_arch_suspend)
     51	lis	r11,swsusp_save_area@h
     52	ori	r11,r11,swsusp_save_area@l
     53
     54	mflr	r0
     55	stw	r0,SL_LR(r11)
     56	mfcr	r0
     57	stw	r0,SL_CR(r11)
     58	stw	r1,SL_SP(r11)
     59	stw	r2,SL_R2(r11)
     60	stmw	r12,SL_R12(r11)
     61
     62	/* Save MSR & TCR */
     63	mfmsr	r4
     64	stw	r4,SL_MSR(r11)
     65	mfspr	r4,SPRN_TCR
     66	stw	r4,SL_TCR(r11)
     67
     68	/* Get a stable timebase and save it */
     691:	mfspr	r4,SPRN_TBRU
     70	stw	r4,SL_TBU(r11)
     71	mfspr	r5,SPRN_TBRL
     72	stw	r5,SL_TBL(r11)
     73	mfspr	r3,SPRN_TBRU
     74	cmpw	r3,r4
     75	bne	1b
     76
     77	/* Save SPRGs */
     78	mfspr	r4,SPRN_SPRG0
     79	stw	r4,SL_SPRG0(r11)
     80	mfspr	r4,SPRN_SPRG1
     81	stw	r4,SL_SPRG1(r11)
     82	mfspr	r4,SPRN_SPRG2
     83	stw	r4,SL_SPRG2(r11)
     84	mfspr	r4,SPRN_SPRG3
     85	stw	r4,SL_SPRG3(r11)
     86	mfspr	r4,SPRN_SPRG4
     87	stw	r4,SL_SPRG4(r11)
     88	mfspr	r4,SPRN_SPRG5
     89	stw	r4,SL_SPRG5(r11)
     90	mfspr	r4,SPRN_SPRG6
     91	stw	r4,SL_SPRG6(r11)
     92	mfspr	r4,SPRN_SPRG7
     93	stw	r4,SL_SPRG7(r11)
     94
     95	/* Call the low level suspend stuff (we should probably have made
     96	 * a stackframe...
     97	 */
     98	bl	swsusp_save
     99
    100	/* Restore LR from the save area */
    101	lis	r11,swsusp_save_area@h
    102	ori	r11,r11,swsusp_save_area@l
    103	lwz	r0,SL_LR(r11)
    104	mtlr	r0
    105
    106	blr
    107
    108_GLOBAL(swsusp_arch_resume)
    109	sync
    110
    111	/* Load ptr the list of pages to copy in r3 */
    112	lis	r11,(restore_pblist)@h
    113	ori	r11,r11,restore_pblist@l
    114	lwz	r3,0(r11)
    115
    116	/* Copy the pages. This is a very basic implementation, to
    117	 * be replaced by something more cache efficient */
    1181:
    119	li	r0,256
    120	mtctr	r0
    121	lwz	r5,pbe_address(r3)	/* source */
    122	lwz	r6,pbe_orig_address(r3)	/* destination */
    1232:
    124	lwz	r8,0(r5)
    125	lwz	r9,4(r5)
    126	lwz	r10,8(r5)
    127	lwz	r11,12(r5)
    128	addi	r5,r5,16
    129	stw	r8,0(r6)
    130	stw	r9,4(r6)
    131	stw	r10,8(r6)
    132	stw	r11,12(r6)
    133	addi	r6,r6,16
    134	bdnz	2b
    135	lwz	r3,pbe_next(r3)
    136	cmpwi	0,r3,0
    137	bne	1b
    138
    139	bl flush_dcache_L1
    140	bl flush_instruction_cache
    141
    142	lis	r11,swsusp_save_area@h
    143	ori	r11,r11,swsusp_save_area@l
    144
    145	/*
    146	 * Mappings from virtual addresses to physical addresses may be
    147	 * different than they were prior to restoring hibernation state. 
    148	 * Invalidate the TLB so that the boot CPU is using the new
    149	 * mappings.
    150	 */
    151	bl	_tlbil_all
    152
    153	lwz	r4,SL_SPRG0(r11)
    154	mtspr	SPRN_SPRG0,r4
    155	lwz	r4,SL_SPRG1(r11)
    156	mtspr	SPRN_SPRG1,r4
    157	lwz	r4,SL_SPRG2(r11)
    158	mtspr	SPRN_SPRG2,r4
    159	lwz	r4,SL_SPRG3(r11)
    160	mtspr	SPRN_SPRG3,r4
    161	lwz	r4,SL_SPRG4(r11)
    162	mtspr	SPRN_SPRG4,r4
    163	lwz	r4,SL_SPRG5(r11)
    164	mtspr	SPRN_SPRG5,r4
    165	lwz	r4,SL_SPRG6(r11)
    166	mtspr	SPRN_SPRG6,r4
    167	lwz	r4,SL_SPRG7(r11)
    168	mtspr	SPRN_SPRG7,r4
    169
    170	/* restore the MSR */
    171	lwz	r3,SL_MSR(r11)
    172	mtmsr	r3
    173
    174	/* Restore TB */
    175	li	r3,0
    176	mtspr	SPRN_TBWL,r3
    177	lwz	r3,SL_TBU(r11)
    178	lwz	r4,SL_TBL(r11)
    179	mtspr	SPRN_TBWU,r3
    180	mtspr	SPRN_TBWL,r4
    181
    182	/* Restore TCR and clear any pending bits in TSR. */
    183	lwz	r4,SL_TCR(r11)
    184	mtspr	SPRN_TCR,r4
    185	lis	r4, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
    186	mtspr	SPRN_TSR,r4
    187
    188	/* Kick decrementer */
    189	li	r0,1
    190	mtdec	r0
    191
    192	/* Restore the callee-saved registers and return */
    193	lwz	r0,SL_CR(r11)
    194	mtcr	r0
    195	lwz	r2,SL_R2(r11)
    196	lmw	r12,SL_R12(r11)
    197	lwz	r1,SL_SP(r11)
    198	lwz	r0,SL_LR(r11)
    199	mtlr	r0
    200
    201	li	r3,0
    202	blr