Skip to content
misc_32.S 24.6 KiB
Newer Older
	mr	r4, r5				/* EPN = RPN */
	ori	r4, r4, (PPC47x_TLB0_VALID | PPC47x_TLB0_256M)
	insrwi	r4, r7, 1, 21			/* Insert the TS to Word 0 */

	tlbwe	r4, r3, 0			/* Write out the entries */
	tlbwe	r5, r3, 1
	tlbwe	r6, r3, 2
	addi	r8, r8, 1
	cmpwi	r8, 8				/* Have we completed ? */
	bne	write_utlb

	/* make sure we complete the TLB write up */
	isync

	/* 
	 * Prepare to jump to the 1:1 mapping.
	 * 1) Extract page size of the tmp mapping
	 *    DSIZ = TLB_Word0[22:27]
	 * 2) Calculate the physical address of the address
	 *    to jump to.
	 */
	rlwinm	r10, r24, 0, 22, 27

	cmpwi	r10, PPC47x_TLB0_4K
	bne	0f
	li	r10, 0x1000			/* r10 = 4k */
	bl	1f

0:
	/* Defaults to 256M */
	lis	r10, 0x1000
	
	bl	1f
1:	mflr	r4
	addi	r4, r4, (2f-1b)			/* virtual address  of 2f */

	subi	r11, r10, 1			/* offsetmask = Pagesize - 1 */
	not	r10, r11			/* Pagemask = ~(offsetmask) */

	and	r5, r25, r10			/* Physical page */
	and	r6, r4, r11			/* offset within the current page */

	or	r5, r5, r6			/* Physical address for 2f */

	/* Switch the TS in MSR to the original one */
	mfmsr	r8
	insrwi	r8, r7, 1, 26

	mtspr	SPRN_SRR1, r8
	mtspr	SPRN_SRR0, r5
	rfi

2:
	/* Invalidate the tmp mapping */
	lis	r3, 0x8000			/* Way '0' */

	clrrwi	r24, r24, 12			/* Clear the valid bit */
	tlbwe	r24, r3, 0
	tlbwe	r25, r3, 1
	tlbwe	r26, r3, 2

	/* Make sure we complete the TLB write and flush the shadow TLB */
	isync

#endif

ppc44x_map_done:


	/* Restore the parameters */
	mr	r3, r29
	mr	r4, r30
	mr	r5, r31

	li	r0, 0

	/*
	 * Set Machine Status Register to a known status,
	 * switch the MMU off and jump to 1: in a single step.
	 */

	mr	r8, r0
	ori     r8, r8, MSR_RI|MSR_ME
	mtspr	SPRN_SRR1, r8
	addi	r8, r4, 1f - relocate_new_kernel
	mtspr	SPRN_SRR0, r8
	sync
	rfi

1:
	/* from this point address translation is turned off */
	/* and interrupts are disabled */

	/* set a new stack at the bottom of our page... */
	/* (not really needed now) */
	addi	r1, r4, KEXEC_CONTROL_PAGE_SIZE - 8 /* for LR Save+Back Chain */
	stw	r0, 0(r1)

	/* Do the copies */
	li	r6, 0 /* checksum */
	mr	r0, r3
	b	1f

0:	/* top, read another word for the indirection page */
	lwzu	r0, 4(r3)

1:
	/* is it a destination page? (r8) */
	rlwinm.	r7, r0, 0, 31, 31 /* IND_DESTINATION (1<<0) */
	beq	2f

	rlwinm	r8, r0, 0, 0, 19 /* clear kexec flags, page align */
	b	0b

2:	/* is it an indirection page? (r3) */
	rlwinm.	r7, r0, 0, 30, 30 /* IND_INDIRECTION (1<<1) */
	beq	2f

	rlwinm	r3, r0, 0, 0, 19 /* clear kexec flags, page align */
	subi	r3, r3, 4
	b	0b

2:	/* are we done? */
	rlwinm.	r7, r0, 0, 29, 29 /* IND_DONE (1<<2) */
	beq	2f
	b	3f

2:	/* is it a source page? (r9) */
	rlwinm.	r7, r0, 0, 28, 28 /* IND_SOURCE (1<<3) */
	beq	0b

	rlwinm	r9, r0, 0, 0, 19 /* clear kexec flags, page align */

	li	r7, PAGE_SIZE / 4
	mtctr   r7
	subi    r9, r9, 4
	subi    r8, r8, 4
9:
	lwzu    r0, 4(r9)  /* do the copy */
	xor	r6, r6, r0
	stwu    r0, 4(r8)
	dcbst	0, r8
	sync
	icbi	0, r8
	bdnz    9b

	addi    r9, r9, 4
	addi    r8, r8, 4
	b	0b

3:

	/* To be certain of avoiding problems with self-modifying code
	 * execute a serializing instruction here.
	 */
	isync
	sync

	mfspr	r3, SPRN_PIR /* current core we are running on */
	mr	r4, r5 /* load physical address of chunk called */

	/* jump to the entry point, usually the setup routine */
	mtlr	r5
	blrl

1:	b	1b

relocate_new_kernel_end:

	.globl relocate_new_kernel_size
relocate_new_kernel_size:
	.long relocate_new_kernel_end - relocate_new_kernel
#endif