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 (9186B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 * This file contains sleep low-level functions for PowerBook G3.
      4 *    Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)
      5 *    and Paul Mackerras (paulus@samba.org).
      6 */
      7
      8#include <asm/processor.h>
      9#include <asm/page.h>
     10#include <asm/ppc_asm.h>
     11#include <asm/cputable.h>
     12#include <asm/cache.h>
     13#include <asm/thread_info.h>
     14#include <asm/asm-offsets.h>
     15#include <asm/mmu.h>
     16#include <asm/feature-fixups.h>
     17
     18#define MAGIC	0x4c617273	/* 'Lars' */
     19
     20/*
     21 * Structure for storing CPU registers on the stack.
     22 */
     23#define SL_SP		0
     24#define SL_PC		4
     25#define SL_MSR		8
     26#define SL_SDR1		0xc
     27#define SL_SPRG0	0x10	/* 4 sprg's */
     28#define SL_DBAT0	0x20
     29#define SL_IBAT0	0x28
     30#define SL_DBAT1	0x30
     31#define SL_IBAT1	0x38
     32#define SL_DBAT2	0x40
     33#define SL_IBAT2	0x48
     34#define SL_DBAT3	0x50
     35#define SL_IBAT3	0x58
     36#define SL_DBAT4	0x60
     37#define SL_IBAT4	0x68
     38#define SL_DBAT5	0x70
     39#define SL_IBAT5	0x78
     40#define SL_DBAT6	0x80
     41#define SL_IBAT6	0x88
     42#define SL_DBAT7	0x90
     43#define SL_IBAT7	0x98
     44#define SL_TB		0xa0
     45#define SL_R2		0xa8
     46#define SL_CR		0xac
     47#define SL_LR		0xb0
     48#define SL_R12		0xb4	/* r12 to r31 */
     49#define SL_SIZE		(SL_R12 + 80)
     50
     51	.section .text
     52	.align	5
     53
     54#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) || \
     55    (defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32))
     56
     57/* This gets called by via-pmu.c late during the sleep process.
     58 * The PMU was already send the sleep command and will shut us down
     59 * soon. We need to save all that is needed and setup the wakeup
     60 * vector that will be called by the ROM on wakeup
     61 */
     62_GLOBAL(low_sleep_handler)
     63#ifndef CONFIG_PPC_BOOK3S_32
     64	blr
     65#else
     66	mflr	r0
     67	lis	r11,sleep_storage@ha
     68	addi	r11,r11,sleep_storage@l
     69	stw	r0,SL_LR(r11)
     70	mfcr	r0
     71	stw	r0,SL_CR(r11)
     72	stw	r1,SL_SP(r11)
     73	stw	r2,SL_R2(r11)
     74	stmw	r12,SL_R12(r11)
     75
     76	/* Save MSR & SDR1 */
     77	mfmsr	r4
     78	stw	r4,SL_MSR(r11)
     79	mfsdr1	r4
     80	stw	r4,SL_SDR1(r11)
     81
     82	/* Get a stable timebase and save it */
     831:	mftbu	r4
     84	stw	r4,SL_TB(r11)
     85	mftb	r5
     86	stw	r5,SL_TB+4(r11)
     87	mftbu	r3
     88	cmpw	r3,r4
     89	bne	1b
     90
     91	/* Save SPRGs */
     92	mfsprg	r4,0
     93	stw	r4,SL_SPRG0(r11)
     94	mfsprg	r4,1
     95	stw	r4,SL_SPRG0+4(r11)
     96	mfsprg	r4,2
     97	stw	r4,SL_SPRG0+8(r11)
     98	mfsprg	r4,3
     99	stw	r4,SL_SPRG0+12(r11)
    100
    101	/* Save BATs */
    102	mfdbatu	r4,0
    103	stw	r4,SL_DBAT0(r11)
    104	mfdbatl	r4,0
    105	stw	r4,SL_DBAT0+4(r11)
    106	mfdbatu	r4,1
    107	stw	r4,SL_DBAT1(r11)
    108	mfdbatl	r4,1
    109	stw	r4,SL_DBAT1+4(r11)
    110	mfdbatu	r4,2
    111	stw	r4,SL_DBAT2(r11)
    112	mfdbatl	r4,2
    113	stw	r4,SL_DBAT2+4(r11)
    114	mfdbatu	r4,3
    115	stw	r4,SL_DBAT3(r11)
    116	mfdbatl	r4,3
    117	stw	r4,SL_DBAT3+4(r11)
    118	mfibatu	r4,0
    119	stw	r4,SL_IBAT0(r11)
    120	mfibatl	r4,0
    121	stw	r4,SL_IBAT0+4(r11)
    122	mfibatu	r4,1
    123	stw	r4,SL_IBAT1(r11)
    124	mfibatl	r4,1
    125	stw	r4,SL_IBAT1+4(r11)
    126	mfibatu	r4,2
    127	stw	r4,SL_IBAT2(r11)
    128	mfibatl	r4,2
    129	stw	r4,SL_IBAT2+4(r11)
    130	mfibatu	r4,3
    131	stw	r4,SL_IBAT3(r11)
    132	mfibatl	r4,3
    133	stw	r4,SL_IBAT3+4(r11)
    134
    135BEGIN_MMU_FTR_SECTION
    136	mfspr	r4,SPRN_DBAT4U
    137	stw	r4,SL_DBAT4(r11)
    138	mfspr	r4,SPRN_DBAT4L
    139	stw	r4,SL_DBAT4+4(r11)
    140	mfspr	r4,SPRN_DBAT5U
    141	stw	r4,SL_DBAT5(r11)
    142	mfspr	r4,SPRN_DBAT5L
    143	stw	r4,SL_DBAT5+4(r11)
    144	mfspr	r4,SPRN_DBAT6U
    145	stw	r4,SL_DBAT6(r11)
    146	mfspr	r4,SPRN_DBAT6L
    147	stw	r4,SL_DBAT6+4(r11)
    148	mfspr	r4,SPRN_DBAT7U
    149	stw	r4,SL_DBAT7(r11)
    150	mfspr	r4,SPRN_DBAT7L
    151	stw	r4,SL_DBAT7+4(r11)
    152	mfspr	r4,SPRN_IBAT4U
    153	stw	r4,SL_IBAT4(r11)
    154	mfspr	r4,SPRN_IBAT4L
    155	stw	r4,SL_IBAT4+4(r11)
    156	mfspr	r4,SPRN_IBAT5U
    157	stw	r4,SL_IBAT5(r11)
    158	mfspr	r4,SPRN_IBAT5L
    159	stw	r4,SL_IBAT5+4(r11)
    160	mfspr	r4,SPRN_IBAT6U
    161	stw	r4,SL_IBAT6(r11)
    162	mfspr	r4,SPRN_IBAT6L
    163	stw	r4,SL_IBAT6+4(r11)
    164	mfspr	r4,SPRN_IBAT7U
    165	stw	r4,SL_IBAT7(r11)
    166	mfspr	r4,SPRN_IBAT7L
    167	stw	r4,SL_IBAT7+4(r11)
    168END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
    169
    170	/* Backup various CPU config stuffs */
    171	bl	__save_cpu_setup
    172
    173	/* The ROM can wake us up via 2 different vectors:
    174	 *  - On wallstreet & lombard, we must write a magic
    175	 *    value 'Lars' at address 4 and a pointer to a
    176	 *    memory location containing the PC to resume from
    177	 *    at address 0.
    178	 *  - On Core99, we must store the wakeup vector at
    179	 *    address 0x80 and eventually it's parameters
    180	 *    at address 0x84. I've have some trouble with those
    181	 *    parameters however and I no longer use them.
    182	 */
    183	lis	r5,grackle_wake_up@ha
    184	addi	r5,r5,grackle_wake_up@l
    185	tophys(r5,r5)
    186	stw	r5,SL_PC(r11)
    187	lis	r4,KERNELBASE@h
    188	tophys(r5,r11)
    189	addi	r5,r5,SL_PC
    190	lis	r6,MAGIC@ha
    191	addi	r6,r6,MAGIC@l
    192	stw	r5,0(r4)
    193	stw	r6,4(r4)
    194	/* Setup stuffs at 0x80-0x84 for Core99 */
    195	lis	r3,core99_wake_up@ha
    196	addi	r3,r3,core99_wake_up@l
    197	tophys(r3,r3)
    198	stw	r3,0x80(r4)
    199	stw	r5,0x84(r4)
    200
    201	.globl	low_cpu_offline_self
    202low_cpu_offline_self:
    203	/* Flush & disable all caches */
    204	bl	flush_disable_caches
    205
    206	/* Turn off data relocation. */
    207	mfmsr	r3		/* Save MSR in r7 */
    208	rlwinm	r3,r3,0,28,26	/* Turn off DR bit */
    209	sync
    210	mtmsr	r3
    211	isync
    212
    213BEGIN_FTR_SECTION
    214	/* Flush any pending L2 data prefetches to work around HW bug */
    215	sync
    216	lis	r3,0xfff0
    217	lwz	r0,0(r3)	/* perform cache-inhibited load to ROM */
    218	sync			/* (caches are disabled at this point) */
    219END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
    220
    221/*
    222 * Set the HID0 and MSR for sleep.
    223 */
    224	mfspr	r2,SPRN_HID0
    225	rlwinm	r2,r2,0,10,7	/* clear doze, nap */
    226	oris	r2,r2,HID0_SLEEP@h
    227	sync
    228	isync
    229	mtspr	SPRN_HID0,r2
    230	sync
    231
    232/* This loop puts us back to sleep in case we have a spurrious
    233 * wakeup so that the host bridge properly stays asleep. The
    234 * CPU will be turned off, either after a known time (about 1
    235 * second) on wallstreet & lombard, or as soon as the CPU enters
    236 * SLEEP mode on core99
    237 */
    238	mfmsr	r2
    239	oris	r2,r2,MSR_POW@h
    2401:	sync
    241	mtmsr	r2
    242	isync
    243	b	1b
    244_ASM_NOKPROBE_SYMBOL(low_cpu_offline_self)
    245/*
    246 * Here is the resume code.
    247 */
    248
    249
    250/*
    251 * Core99 machines resume here
    252 * r4 has the physical address of SL_PC(sp) (unused)
    253 */
    254_GLOBAL(core99_wake_up)
    255	/* Make sure HID0 no longer contains any sleep bit and that data cache
    256	 * is disabled
    257	 */
    258	mfspr	r3,SPRN_HID0
    259	rlwinm	r3,r3,0,11,7		/* clear SLEEP, NAP, DOZE bits */
    260	rlwinm	3,r3,0,18,15		/* clear DCE, ICE */
    261	mtspr	SPRN_HID0,r3
    262	sync
    263	isync
    264
    265	/* sanitize MSR */
    266	mfmsr	r3
    267	ori	r3,r3,MSR_EE|MSR_IP
    268	xori	r3,r3,MSR_EE|MSR_IP
    269	sync
    270	isync
    271	mtmsr	r3
    272	sync
    273	isync
    274
    275	/* Recover sleep storage */
    276	lis	r3,sleep_storage@ha
    277	addi	r3,r3,sleep_storage@l
    278	tophys(r3,r3)
    279	addi	r1,r3,SL_PC
    280
    281	/* Pass thru to older resume code ... */
    282_ASM_NOKPROBE_SYMBOL(core99_wake_up)
    283/*
    284 * Here is the resume code for older machines.
    285 * r1 has the physical address of SL_PC(sp).
    286 */
    287
    288grackle_wake_up:
    289
    290	/* Restore the kernel's segment registers before
    291	 * we do any r1 memory access as we are not sure they
    292	 * are in a sane state above the first 256Mb region
    293	 */
    294	bl	load_segment_registers
    295	sync
    296	isync
    297
    298	subi	r1,r1,SL_PC
    299
    300	/* Restore various CPU config stuffs */
    301	bl	__restore_cpu_setup
    302
    303	/* Make sure all FPRs have been initialized */
    304	bl	reloc_offset
    305	bl	__init_fpu_registers
    306
    307	/* Invalidate & enable L1 cache, we don't care about
    308	 * whatever the ROM may have tried to write to memory
    309	 */
    310	bl	__inval_enable_L1
    311
    312	/* Restore the BATs, and SDR1.  Then we can turn on the MMU. */
    313	lwz	r4,SL_SDR1(r1)
    314	mtsdr1	r4
    315	lwz	r4,SL_SPRG0(r1)
    316	mtsprg	0,r4
    317	lwz	r4,SL_SPRG0+4(r1)
    318	mtsprg	1,r4
    319	lwz	r4,SL_SPRG0+8(r1)
    320	mtsprg	2,r4
    321	lwz	r4,SL_SPRG0+12(r1)
    322	mtsprg	3,r4
    323
    324	lwz	r4,SL_DBAT0(r1)
    325	mtdbatu	0,r4
    326	lwz	r4,SL_DBAT0+4(r1)
    327	mtdbatl	0,r4
    328	lwz	r4,SL_DBAT1(r1)
    329	mtdbatu	1,r4
    330	lwz	r4,SL_DBAT1+4(r1)
    331	mtdbatl	1,r4
    332	lwz	r4,SL_DBAT2(r1)
    333	mtdbatu	2,r4
    334	lwz	r4,SL_DBAT2+4(r1)
    335	mtdbatl	2,r4
    336	lwz	r4,SL_DBAT3(r1)
    337	mtdbatu	3,r4
    338	lwz	r4,SL_DBAT3+4(r1)
    339	mtdbatl	3,r4
    340	lwz	r4,SL_IBAT0(r1)
    341	mtibatu	0,r4
    342	lwz	r4,SL_IBAT0+4(r1)
    343	mtibatl	0,r4
    344	lwz	r4,SL_IBAT1(r1)
    345	mtibatu	1,r4
    346	lwz	r4,SL_IBAT1+4(r1)
    347	mtibatl	1,r4
    348	lwz	r4,SL_IBAT2(r1)
    349	mtibatu	2,r4
    350	lwz	r4,SL_IBAT2+4(r1)
    351	mtibatl	2,r4
    352	lwz	r4,SL_IBAT3(r1)
    353	mtibatu	3,r4
    354	lwz	r4,SL_IBAT3+4(r1)
    355	mtibatl	3,r4
    356
    357BEGIN_MMU_FTR_SECTION
    358	lwz	r4,SL_DBAT4(r1)
    359	mtspr	SPRN_DBAT4U,r4
    360	lwz	r4,SL_DBAT4+4(r1)
    361	mtspr	SPRN_DBAT4L,r4
    362	lwz	r4,SL_DBAT5(r1)
    363	mtspr	SPRN_DBAT5U,r4
    364	lwz	r4,SL_DBAT5+4(r1)
    365	mtspr	SPRN_DBAT5L,r4
    366	lwz	r4,SL_DBAT6(r1)
    367	mtspr	SPRN_DBAT6U,r4
    368	lwz	r4,SL_DBAT6+4(r1)
    369	mtspr	SPRN_DBAT6L,r4
    370	lwz	r4,SL_DBAT7(r1)
    371	mtspr	SPRN_DBAT7U,r4
    372	lwz	r4,SL_DBAT7+4(r1)
    373	mtspr	SPRN_DBAT7L,r4
    374	lwz	r4,SL_IBAT4(r1)
    375	mtspr	SPRN_IBAT4U,r4
    376	lwz	r4,SL_IBAT4+4(r1)
    377	mtspr	SPRN_IBAT4L,r4
    378	lwz	r4,SL_IBAT5(r1)
    379	mtspr	SPRN_IBAT5U,r4
    380	lwz	r4,SL_IBAT5+4(r1)
    381	mtspr	SPRN_IBAT5L,r4
    382	lwz	r4,SL_IBAT6(r1)
    383	mtspr	SPRN_IBAT6U,r4
    384	lwz	r4,SL_IBAT6+4(r1)
    385	mtspr	SPRN_IBAT6L,r4
    386	lwz	r4,SL_IBAT7(r1)
    387	mtspr	SPRN_IBAT7U,r4
    388	lwz	r4,SL_IBAT7+4(r1)
    389	mtspr	SPRN_IBAT7L,r4
    390END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
    391
    392	/* Flush all TLBs */
    393	lis	r4,0x1000
    3941:	addic.	r4,r4,-0x1000
    395	tlbie	r4
    396	blt	1b
    397	sync
    398
    399	/* Restore TB */
    400	li	r3,0
    401	mttbl	r3
    402	lwz	r3,SL_TB(r1)
    403	lwz	r4,SL_TB+4(r1)
    404	mttbu	r3
    405	mttbl	r4
    406
    407	/* Restore the callee-saved registers and return */
    408	lwz	r0,SL_CR(r1)
    409	mtcr	r0
    410	lwz	r2,SL_R2(r1)
    411	lmw	r12,SL_R12(r1)
    412
    413	/* restore the MSR and SP and turn on the MMU and return */
    414	lwz	r3,SL_MSR(r1)
    415	lwz	r4,SL_LR(r1)
    416	lwz	r1,SL_SP(r1)
    417	mtsrr0	r4
    418	mtsrr1	r3
    419	sync
    420	isync
    421	rfi
    422_ASM_NOKPROBE_SYMBOL(grackle_wake_up)
    423
    424#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
    425
    426	.section .bss
    427	.balign	L1_CACHE_BYTES
    428sleep_storage:
    429	.space SL_SIZE
    430	.balign	L1_CACHE_BYTES, 0
    431
    432#endif /* CONFIG_PPC_BOOK3S_32 */
    433	.section .text