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_32.S (8273B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#include <linux/threads.h>
      3#include <asm/processor.h>
      4#include <asm/page.h>
      5#include <asm/cputable.h>
      6#include <asm/thread_info.h>
      7#include <asm/ppc_asm.h>
      8#include <asm/asm-offsets.h>
      9#include <asm/mmu.h>
     10#include <asm/feature-fixups.h>
     11
     12/*
     13 * Structure for storing CPU registers on the save area.
     14 */
     15#define SL_SP		0
     16#define SL_PC		4
     17#define SL_MSR		8
     18#define SL_SDR1		0xc
     19#define SL_SPRG0	0x10	/* 4 sprg's */
     20#define SL_DBAT0	0x20
     21#define SL_IBAT0	0x28
     22#define SL_DBAT1	0x30
     23#define SL_IBAT1	0x38
     24#define SL_DBAT2	0x40
     25#define SL_IBAT2	0x48
     26#define SL_DBAT3	0x50
     27#define SL_IBAT3	0x58
     28#define SL_DBAT4	0x60
     29#define SL_IBAT4	0x68
     30#define SL_DBAT5	0x70
     31#define SL_IBAT5	0x78
     32#define SL_DBAT6	0x80
     33#define SL_IBAT6	0x88
     34#define SL_DBAT7	0x90
     35#define SL_IBAT7	0x98
     36#define SL_TB		0xa0
     37#define SL_R2		0xa8
     38#define SL_CR		0xac
     39#define SL_LR		0xb0
     40#define SL_R12		0xb4	/* r12 to r31 */
     41#define SL_SIZE		(SL_R12 + 80)
     42
     43	.section .data
     44	.align	5
     45
     46_GLOBAL(swsusp_save_area)
     47	.space	SL_SIZE
     48
     49
     50	.section .text
     51	.align	5
     52
     53_GLOBAL(swsusp_arch_suspend)
     54
     55	lis	r11,swsusp_save_area@h
     56	ori	r11,r11,swsusp_save_area@l
     57
     58	mflr	r0
     59	stw	r0,SL_LR(r11)
     60	mfcr	r0
     61	stw	r0,SL_CR(r11)
     62	stw	r1,SL_SP(r11)
     63	stw	r2,SL_R2(r11)
     64	stmw	r12,SL_R12(r11)
     65
     66	/* Save MSR & SDR1 */
     67	mfmsr	r4
     68	stw	r4,SL_MSR(r11)
     69	mfsdr1	r4
     70	stw	r4,SL_SDR1(r11)
     71
     72	/* Get a stable timebase and save it */
     731:	mftbu	r4
     74	stw	r4,SL_TB(r11)
     75	mftb	r5
     76	stw	r5,SL_TB+4(r11)
     77	mftbu	r3
     78	cmpw	r3,r4
     79	bne	1b
     80
     81	/* Save SPRGs */
     82	mfsprg	r4,0
     83	stw	r4,SL_SPRG0(r11)
     84	mfsprg	r4,1
     85	stw	r4,SL_SPRG0+4(r11)
     86	mfsprg	r4,2
     87	stw	r4,SL_SPRG0+8(r11)
     88	mfsprg	r4,3
     89	stw	r4,SL_SPRG0+12(r11)
     90
     91	/* Save BATs */
     92	mfdbatu	r4,0
     93	stw	r4,SL_DBAT0(r11)
     94	mfdbatl	r4,0
     95	stw	r4,SL_DBAT0+4(r11)
     96	mfdbatu	r4,1
     97	stw	r4,SL_DBAT1(r11)
     98	mfdbatl	r4,1
     99	stw	r4,SL_DBAT1+4(r11)
    100	mfdbatu	r4,2
    101	stw	r4,SL_DBAT2(r11)
    102	mfdbatl	r4,2
    103	stw	r4,SL_DBAT2+4(r11)
    104	mfdbatu	r4,3
    105	stw	r4,SL_DBAT3(r11)
    106	mfdbatl	r4,3
    107	stw	r4,SL_DBAT3+4(r11)
    108	mfibatu	r4,0
    109	stw	r4,SL_IBAT0(r11)
    110	mfibatl	r4,0
    111	stw	r4,SL_IBAT0+4(r11)
    112	mfibatu	r4,1
    113	stw	r4,SL_IBAT1(r11)
    114	mfibatl	r4,1
    115	stw	r4,SL_IBAT1+4(r11)
    116	mfibatu	r4,2
    117	stw	r4,SL_IBAT2(r11)
    118	mfibatl	r4,2
    119	stw	r4,SL_IBAT2+4(r11)
    120	mfibatu	r4,3
    121	stw	r4,SL_IBAT3(r11)
    122	mfibatl	r4,3
    123	stw	r4,SL_IBAT3+4(r11)
    124
    125BEGIN_MMU_FTR_SECTION
    126	mfspr	r4,SPRN_DBAT4U
    127	stw	r4,SL_DBAT4(r11)
    128	mfspr	r4,SPRN_DBAT4L
    129	stw	r4,SL_DBAT4+4(r11)
    130	mfspr	r4,SPRN_DBAT5U
    131	stw	r4,SL_DBAT5(r11)
    132	mfspr	r4,SPRN_DBAT5L
    133	stw	r4,SL_DBAT5+4(r11)
    134	mfspr	r4,SPRN_DBAT6U
    135	stw	r4,SL_DBAT6(r11)
    136	mfspr	r4,SPRN_DBAT6L
    137	stw	r4,SL_DBAT6+4(r11)
    138	mfspr	r4,SPRN_DBAT7U
    139	stw	r4,SL_DBAT7(r11)
    140	mfspr	r4,SPRN_DBAT7L
    141	stw	r4,SL_DBAT7+4(r11)
    142	mfspr	r4,SPRN_IBAT4U
    143	stw	r4,SL_IBAT4(r11)
    144	mfspr	r4,SPRN_IBAT4L
    145	stw	r4,SL_IBAT4+4(r11)
    146	mfspr	r4,SPRN_IBAT5U
    147	stw	r4,SL_IBAT5(r11)
    148	mfspr	r4,SPRN_IBAT5L
    149	stw	r4,SL_IBAT5+4(r11)
    150	mfspr	r4,SPRN_IBAT6U
    151	stw	r4,SL_IBAT6(r11)
    152	mfspr	r4,SPRN_IBAT6L
    153	stw	r4,SL_IBAT6+4(r11)
    154	mfspr	r4,SPRN_IBAT7U
    155	stw	r4,SL_IBAT7(r11)
    156	mfspr	r4,SPRN_IBAT7L
    157	stw	r4,SL_IBAT7+4(r11)
    158END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
    159
    160#if  0
    161	/* Backup various CPU config stuffs */
    162	bl	__save_cpu_setup
    163#endif
    164	/* Call the low level suspend stuff (we should probably have made
    165	 * a stackframe...
    166	 */
    167	bl	swsusp_save
    168
    169	/* Restore LR from the save area */
    170	lis	r11,swsusp_save_area@h
    171	ori	r11,r11,swsusp_save_area@l
    172	lwz	r0,SL_LR(r11)
    173	mtlr	r0
    174
    175	blr
    176
    177
    178/* Resume code */
    179_GLOBAL(swsusp_arch_resume)
    180
    181#ifdef CONFIG_ALTIVEC
    182	/* Stop pending alitvec streams and memory accesses */
    183BEGIN_FTR_SECTION
    184	PPC_DSSALL
    185END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
    186#endif
    187 	sync
    188
    189	/* Disable MSR:DR to make sure we don't take a TLB or
    190	 * hash miss during the copy, as our hash table will
    191	 * for a while be unusable. For .text, we assume we are
    192	 * covered by a BAT. This works only for non-G5 at this
    193	 * point. G5 will need a better approach, possibly using
    194	 * a small temporary hash table filled with large mappings,
    195	 * disabling the MMU completely isn't a good option for
    196	 * performance reasons.
    197	 * (Note that 750's may have the same performance issue as
    198	 * the G5 in this case, we should investigate using moving
    199	 * BATs for these CPUs)
    200	 */
    201	mfmsr	r0
    202	sync
    203	rlwinm	r0,r0,0,28,26		/* clear MSR_DR */
    204	mtmsr	r0
    205	sync
    206	isync
    207
    208	/* Load ptr the list of pages to copy in r3 */
    209	lis	r11,(restore_pblist - KERNELBASE)@h
    210	ori	r11,r11,restore_pblist@l
    211	lwz	r10,0(r11)
    212
    213	/* Copy the pages. This is a very basic implementation, to
    214	 * be replaced by something more cache efficient */
    2151:
    216	tophys(r3,r10)
    217	li	r0,256
    218	mtctr	r0
    219	lwz	r11,pbe_address(r3)	/* source */
    220	tophys(r5,r11)
    221	lwz	r10,pbe_orig_address(r3)	/* destination */
    222	tophys(r6,r10)
    2232:
    224	lwz	r8,0(r5)
    225	lwz	r9,4(r5)
    226	lwz	r10,8(r5)
    227	lwz	r11,12(r5)
    228	addi	r5,r5,16
    229	stw	r8,0(r6)
    230	stw	r9,4(r6)
    231	stw	r10,8(r6)
    232	stw	r11,12(r6)
    233	addi	r6,r6,16
    234	bdnz	2b
    235	lwz		r10,pbe_next(r3)
    236	cmpwi	0,r10,0
    237	bne	1b
    238
    239	/* Do a very simple cache flush/inval of the L1 to ensure
    240	 * coherency of the icache
    241	 */
    242	lis	r3,0x0002
    243	mtctr	r3
    244	li	r3, 0
    2451:
    246	lwz	r0,0(r3)
    247	addi	r3,r3,0x0020
    248	bdnz	1b
    249	isync
    250	sync
    251
    252	/* Now flush those cache lines */
    253	lis	r3,0x0002
    254	mtctr	r3
    255	li	r3, 0
    2561:
    257	dcbf	0,r3
    258	addi	r3,r3,0x0020
    259	bdnz	1b
    260	sync
    261
    262	/* Ok, we are now running with the kernel data of the old
    263	 * kernel fully restored. We can get to the save area
    264	 * easily now. As for the rest of the code, it assumes the
    265	 * loader kernel and the booted one are exactly identical
    266	 */
    267	lis	r11,swsusp_save_area@h
    268	ori	r11,r11,swsusp_save_area@l
    269	tophys(r11,r11)
    270
    271#if 0
    272	/* Restore various CPU config stuffs */
    273	bl	__restore_cpu_setup
    274#endif
    275	/* Restore the BATs, and SDR1.  Then we can turn on the MMU.
    276	 * This is a bit hairy as we are running out of those BATs,
    277	 * but first, our code is probably in the icache, and we are
    278	 * writing the same value to the BAT, so that should be fine,
    279	 * though a better solution will have to be found long-term
    280	 */
    281	lwz	r4,SL_SDR1(r11)
    282	mtsdr1	r4
    283	lwz	r4,SL_SPRG0(r11)
    284	mtsprg	0,r4
    285	lwz	r4,SL_SPRG0+4(r11)
    286	mtsprg	1,r4
    287	lwz	r4,SL_SPRG0+8(r11)
    288	mtsprg	2,r4
    289	lwz	r4,SL_SPRG0+12(r11)
    290	mtsprg	3,r4
    291
    292#if 0
    293	lwz	r4,SL_DBAT0(r11)
    294	mtdbatu	0,r4
    295	lwz	r4,SL_DBAT0+4(r11)
    296	mtdbatl	0,r4
    297	lwz	r4,SL_DBAT1(r11)
    298	mtdbatu	1,r4
    299	lwz	r4,SL_DBAT1+4(r11)
    300	mtdbatl	1,r4
    301	lwz	r4,SL_DBAT2(r11)
    302	mtdbatu	2,r4
    303	lwz	r4,SL_DBAT2+4(r11)
    304	mtdbatl	2,r4
    305	lwz	r4,SL_DBAT3(r11)
    306	mtdbatu	3,r4
    307	lwz	r4,SL_DBAT3+4(r11)
    308	mtdbatl	3,r4
    309	lwz	r4,SL_IBAT0(r11)
    310	mtibatu	0,r4
    311	lwz	r4,SL_IBAT0+4(r11)
    312	mtibatl	0,r4
    313	lwz	r4,SL_IBAT1(r11)
    314	mtibatu	1,r4
    315	lwz	r4,SL_IBAT1+4(r11)
    316	mtibatl	1,r4
    317	lwz	r4,SL_IBAT2(r11)
    318	mtibatu	2,r4
    319	lwz	r4,SL_IBAT2+4(r11)
    320	mtibatl	2,r4
    321	lwz	r4,SL_IBAT3(r11)
    322	mtibatu	3,r4
    323	lwz	r4,SL_IBAT3+4(r11)
    324	mtibatl	3,r4
    325BEGIN_MMU_FTR_SECTION
    326	lwz	r4,SL_DBAT4(r11)
    327	mtspr	SPRN_DBAT4U,r4
    328	lwz	r4,SL_DBAT4+4(r11)
    329	mtspr	SPRN_DBAT4L,r4
    330	lwz	r4,SL_DBAT5(r11)
    331	mtspr	SPRN_DBAT5U,r4
    332	lwz	r4,SL_DBAT5+4(r11)
    333	mtspr	SPRN_DBAT5L,r4
    334	lwz	r4,SL_DBAT6(r11)
    335	mtspr	SPRN_DBAT6U,r4
    336	lwz	r4,SL_DBAT6+4(r11)
    337	mtspr	SPRN_DBAT6L,r4
    338	lwz	r4,SL_DBAT7(r11)
    339	mtspr	SPRN_DBAT7U,r4
    340	lwz	r4,SL_DBAT7+4(r11)
    341	mtspr	SPRN_DBAT7L,r4
    342	lwz	r4,SL_IBAT4(r11)
    343	mtspr	SPRN_IBAT4U,r4
    344	lwz	r4,SL_IBAT4+4(r11)
    345	mtspr	SPRN_IBAT4L,r4
    346	lwz	r4,SL_IBAT5(r11)
    347	mtspr	SPRN_IBAT5U,r4
    348	lwz	r4,SL_IBAT5+4(r11)
    349	mtspr	SPRN_IBAT5L,r4
    350	lwz	r4,SL_IBAT6(r11)
    351	mtspr	SPRN_IBAT6U,r4
    352	lwz	r4,SL_IBAT6+4(r11)
    353	mtspr	SPRN_IBAT6L,r4
    354	lwz	r4,SL_IBAT7(r11)
    355	mtspr	SPRN_IBAT7U,r4
    356	lwz	r4,SL_IBAT7+4(r11)
    357	mtspr	SPRN_IBAT7L,r4
    358END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
    359#endif
    360
    361	/* Flush all TLBs */
    362	lis	r4,0x1000
    3631:	addic.	r4,r4,-0x1000
    364	tlbie	r4
    365	bgt	1b
    366	sync
    367
    368	/* restore the MSR and turn on the MMU */
    369	lwz	r3,SL_MSR(r11)
    370	bl	turn_on_mmu
    371	tovirt(r11,r11)
    372
    373	/* Restore TB */
    374	li	r3,0
    375	mttbl	r3
    376	lwz	r3,SL_TB(r11)
    377	lwz	r4,SL_TB+4(r11)
    378	mttbu	r3
    379	mttbl	r4
    380
    381	/* Kick decrementer */
    382	li	r0,1
    383	mtdec	r0
    384
    385	/* Restore the callee-saved registers and return */
    386	lwz	r0,SL_CR(r11)
    387	mtcr	r0
    388	lwz	r2,SL_R2(r11)
    389	lmw	r12,SL_R12(r11)
    390	lwz	r1,SL_SP(r11)
    391	lwz	r0,SL_LR(r11)
    392	mtlr	r0
    393
    394	// XXX Note: we don't really need to call swsusp_resume
    395
    396	li	r3,0
    397	blr
    398_ASM_NOKPROBE_SYMBOL(swsusp_arch_resume)
    399
    400/* FIXME:This construct is actually not useful since we don't shut
    401 * down the instruction MMU, we could just flip back MSR-DR on.
    402 */
    403turn_on_mmu:
    404	mflr	r4
    405	mtsrr0	r4
    406	mtsrr1	r3
    407	sync
    408	isync
    409	rfi
    410_ASM_NOKPROBE_SYMBOL(turn_on_mmu)
    411