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

crt0.S (6798B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 * Copyright (C) Paul Mackerras 1997.
      4 *
      5 * Adapted for 64 bit LE PowerPC by Andrew Tauferner
      6 */
      7
      8#include "ppc_asm.h"
      9
     10RELA = 7
     11RELASZ = 8
     12RELAENT = 9
     13
     14	.data
     15	/* A procedure descriptor used when booting this as a COFF file.
     16	 * When making COFF, this comes first in the link and we're
     17	 * linked at 0x500000.
     18	 */
     19	.globl	_zimage_start_opd
     20_zimage_start_opd:
     21	.long	0x500000, 0, 0, 0
     22	.text
     23	b	_zimage_start
     24
     25#ifdef __powerpc64__
     26.balign 8
     27p_start:	.8byte	_start
     28p_etext:	.8byte	_etext
     29p_bss_start:	.8byte	__bss_start
     30p_end:		.8byte	_end
     31
     32p_toc:		.8byte	.TOC. - p_base
     33p_dyn:		.8byte	__dynamic_start - p_base
     34p_rela:		.8byte	__rela_dyn_start - p_base
     35p_prom:		.8byte	0
     36	.weak	_platform_stack_top
     37p_pstack:	.8byte	_platform_stack_top
     38#else
     39p_start:	.long	_start
     40p_etext:	.long	_etext
     41p_bss_start:	.long	__bss_start
     42p_end:		.long	_end
     43
     44	.weak	_platform_stack_top
     45p_pstack:	.long	_platform_stack_top
     46#endif
     47
     48	.weak	_zimage_start
     49_zimage_start:
     50	.globl	_zimage_start_lib
     51_zimage_start_lib:
     52	/* Work out the offset between the address we were linked at
     53	   and the address where we're running. */
     54	bl	.+4
     55p_base:	mflr	r10		/* r10 now points to runtime addr of p_base */
     56#ifndef __powerpc64__
     57	/* grab the link address of the dynamic section in r11 */
     58	addis	r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha
     59	lwz	r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11)
     60	cmpwi	r11,0
     61	beq	3f		/* if not linked -pie */
     62	/* get the runtime address of the dynamic section in r12 */
     63	.weak	__dynamic_start
     64	addis	r12,r10,(__dynamic_start-p_base)@ha
     65	addi	r12,r12,(__dynamic_start-p_base)@l
     66	subf	r11,r11,r12	/* runtime - linktime offset */
     67
     68	/* The dynamic section contains a series of tagged entries.
     69	 * We need the RELA and RELACOUNT entries. */
     70	li	r9,0
     71	li	r0,0
     729:	lwz	r8,0(r12)	/* get tag */
     73	cmpwi	r8,0
     74	beq	10f		/* end of list */
     75	cmpwi	r8,RELA
     76	bne	11f
     77	lwz	r9,4(r12)	/* get RELA pointer in r9 */
     78	b	12f
     7911:	cmpwi	r8,RELASZ
     80	bne	.Lcheck_for_relaent
     81	lwz	r0,4(r12)       /* get RELASZ value in r0 */
     82	b	12f
     83.Lcheck_for_relaent:
     84	cmpwi	r8,RELAENT
     85	bne	12f
     86	lwz     r14,4(r12)      /* get RELAENT value in r14 */
     8712:	addi	r12,r12,8
     88	b	9b
     89
     90	/* The relocation section contains a list of relocations.
     91	 * We now do the R_PPC_RELATIVE ones, which point to words
     92	 * which need to be initialized with addend + offset */
     9310:	/* skip relocation if we don't have both */
     94	cmpwi	r0,0
     95	beq	3f
     96	cmpwi	r9,0
     97	beq	3f
     98	cmpwi	r14,0
     99	beq	3f
    100
    101	add	r9,r9,r11	/* Relocate RELA pointer */
    102	divwu   r0,r0,r14       /* RELASZ / RELAENT */
    103	mtctr	r0
    1042:	lbz	r0,4+3(r9)	/* ELF32_R_INFO(reloc->r_info) */
    105	cmpwi	r0,22		/* R_PPC_RELATIVE */
    106	bne	.Lnext
    107	lwz	r12,0(r9)	/* reloc->r_offset */
    108	lwz	r0,8(r9)	/* reloc->r_addend */
    109	add	r0,r0,r11
    110	stwx	r0,r11,r12
    111.Lnext:	add	r9,r9,r14
    112	bdnz	2b
    113
    114	/* Do a cache flush for our text, in case the loader didn't */
    1153:	lwz	r9,p_start-p_base(r10)	/* note: these are relocated now */
    116	lwz	r8,p_etext-p_base(r10)
    1174:	dcbf	r0,r9
    118	icbi	r0,r9
    119	addi	r9,r9,0x20
    120	cmplw	cr0,r9,r8
    121	blt	4b
    122	sync
    123	isync
    124
    125	/* Clear the BSS */
    126	lwz	r9,p_bss_start-p_base(r10)
    127	lwz	r8,p_end-p_base(r10)
    128	li	r0,0
    1295:	stw	r0,0(r9)
    130	addi	r9,r9,4
    131	cmplw	cr0,r9,r8
    132	blt	5b
    133
    134	/* Possibly set up a custom stack */
    135	lwz	r8,p_pstack-p_base(r10)
    136	cmpwi	r8,0
    137	beq	6f
    138	lwz	r1,0(r8)
    139	li	r0,0
    140	stwu	r0,-16(r1)	/* establish a stack frame */
    1416:
    142#else /* __powerpc64__ */
    143	/* Save the prom pointer at p_prom. */
    144	std	r5,(p_prom-p_base)(r10)
    145
    146	/* Set r2 to the TOC. */
    147	ld	r2,(p_toc-p_base)(r10)
    148	add	r2,r2,r10
    149
    150	/* Grab the link address of the dynamic section in r11. */
    151	ld	r11,-32768(r2)
    152	cmpwi	r11,0
    153	beq	3f              /* if not linked -pie then no dynamic section */
    154
    155	ld	r11,(p_dyn-p_base)(r10)
    156	add	r11,r11,r10
    157	ld	r9,(p_rela-p_base)(r10)
    158	add	r9,r9,r10
    159
    160	li	r13,0
    161	li	r8,0
    1629:	ld	r12,0(r11)       /* get tag */
    163	cmpdi	r12,0
    164	beq	12f              /* end of list */
    165	cmpdi	r12,RELA
    166	bne	10f
    167	ld	r13,8(r11)       /* get RELA pointer in r13 */
    168	b	11f
    16910:	cmpwi   r12,RELASZ
    170	bne	.Lcheck_for_relaent
    171	lwz	r8,8(r11)	/* get RELASZ pointer in r8 */
    172	b	11f
    173.Lcheck_for_relaent:
    174	cmpwi	r12,RELAENT
    175	bne     11f
    176	lwz     r14,8(r11)      /* get RELAENT pointer in r14 */
    17711:	addi	r11,r11,16
    178	b	9b
    17912:
    180	cmpdi	r13,0            /* check we have both RELA, RELASZ, RELAENT*/
    181	cmpdi	cr1,r8,0
    182	beq	3f
    183	beq	cr1,3f
    184	cmpdi	r14,0
    185	beq	3f
    186
    187	/* Calcuate the runtime offset. */
    188	subf	r13,r13,r9
    189
    190	/* Run through the list of relocations and process the
    191	 * R_PPC64_RELATIVE ones. */
    192	divdu   r8,r8,r14       /* RELASZ / RELAENT */
    193	mtctr	r8
    19413:	ld	r0,8(r9)        /* ELF64_R_TYPE(reloc->r_info) */
    195	cmpdi	r0,22           /* R_PPC64_RELATIVE */
    196	bne	.Lnext
    197	ld	r12,0(r9)        /* reloc->r_offset */
    198	ld	r0,16(r9)       /* reloc->r_addend */
    199	add	r0,r0,r13
    200	stdx	r0,r13,r12
    201.Lnext:	add	r9,r9,r14
    202	bdnz	13b
    203
    204	/* Do a cache flush for our text, in case the loader didn't */
    2053:	ld	r9,p_start-p_base(r10)	/* note: these are relocated now */
    206	ld	r8,p_etext-p_base(r10)
    2074:	dcbf	r0,r9
    208	icbi	r0,r9
    209	addi	r9,r9,0x20
    210	cmpld	cr0,r9,r8
    211	blt	4b
    212	sync
    213	isync
    214
    215	/* Clear the BSS */
    216	ld	r9,p_bss_start-p_base(r10)
    217	ld	r8,p_end-p_base(r10)
    218	li	r0,0
    2195:	std	r0,0(r9)
    220	addi	r9,r9,8
    221	cmpld	cr0,r9,r8
    222	blt	5b
    223
    224	/* Possibly set up a custom stack */
    225	ld	r8,p_pstack-p_base(r10)
    226	cmpdi	r8,0
    227	beq	6f
    228	ld	r1,0(r8)
    229	li	r0,0
    230	stdu	r0,-112(r1)	/* establish a stack frame */
    2316:
    232#endif  /* __powerpc64__ */
    233	/* Call platform_init() */
    234	bl	platform_init
    235
    236	/* Call start */
    237	b	start
    238
    239#ifdef __powerpc64__
    240
    241#define PROM_FRAME_SIZE 512
    242
    243.macro OP_REGS op, width, start, end, base, offset
    244	.Lreg=\start
    245	.rept (\end - \start + 1)
    246	\op	.Lreg,\offset+\width*.Lreg(\base)
    247	.Lreg=.Lreg+1
    248	.endr
    249.endm
    250
    251#define SAVE_GPRS(start, end, base)	OP_REGS std, 8, start, end, base, 0
    252#define REST_GPRS(start, end, base)	OP_REGS ld, 8, start, end, base, 0
    253#define SAVE_GPR(n, base)		SAVE_GPRS(n, n, base)
    254#define REST_GPR(n, base)		REST_GPRS(n, n, base)
    255
    256/* prom handles the jump into and return from firmware.  The prom args pointer
    257   is loaded in r3. */
    258.globl prom
    259prom:
    260	mflr	r0
    261	std	r0,16(r1)
    262	stdu	r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
    263
    264	SAVE_GPR(2, r1)
    265	SAVE_GPRS(13, 31, r1)
    266	mfcr    r10
    267	std     r10,8*32(r1)
    268	mfmsr   r10
    269	std     r10,8*33(r1)
    270
    271	/* remove MSR_LE from msr but keep MSR_SF */
    272	mfmsr	r10
    273	rldicr	r10,r10,0,62
    274	mtsrr1	r10
    275
    276	/* Load FW address, set LR to label 1, and jump to FW */
    277	bl	0f
    2780:	mflr	r10
    279	addi	r11,r10,(1f-0b)
    280	mtlr	r11
    281
    282	ld	r10,(p_prom-0b)(r10)
    283	mtsrr0	r10
    284
    285	rfid
    286
    2871:	/* Return from OF */
    288	FIXUP_ENDIAN
    289
    290	/* Restore registers and return. */
    291	rldicl  r1,r1,0,32
    292
    293	/* Restore the MSR (back to 64 bits) */
    294	ld      r10,8*(33)(r1)
    295	mtmsr	r10
    296	isync
    297
    298	/* Restore other registers */
    299	REST_GPR(2, r1)
    300	REST_GPRS(13, 31, r1)
    301	ld      r10,8*32(r1)
    302	mtcr	r10
    303
    304	addi    r1,r1,PROM_FRAME_SIZE
    305	ld      r0,16(r1)
    306	mtlr    r0
    307	blr
    308#endif