Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2321f337 authored by Joakim Tjernlund's avatar Joakim Tjernlund Committed by Benjamin Herrenschmidt
Browse files

powerpc/8xx: Remove DIRTY pte handling in DTLB Error.



There is no need to do set the DIRTY bit directly in DTLB Error.
Trap to do_page_fault() and let the generic MM code do the work.

Signed-off-by: default avatarJoakim Tjernlund <Joakim.Tjernlund@transmode.se>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 15d914d7
Loading
Loading
Loading
Loading
+0 −96
Original line number Diff line number Diff line
@@ -500,102 +500,6 @@ DataTLBError:
	cmpwi	cr0, r10, 0x00f0
	beq-	FixupDAR	/* must be a buggy dcbX, icbi insn. */
DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */
	mfspr	r11, SPRN_DSISR
	/* As the DAR fixup may clear store we may have all 3 states zero.
	 * Make sure only 0x0200(store) falls down into DIRTY handling
	 */
	andis.	r11, r11, 0x4a00	/* !translation, protection or store */
	srwi	r11, r11, 16
	cmpwi	cr0, r11, 0x0200	/* just store ? */
	bne	2f
	/* Only Change bit left now, do it here as it is faster
	 * than trapping to the C fault handler.
	*/

	/* The EA of a data TLB miss is automatically stored in the MD_EPN
	 * register.  The EA of a data TLB error is automatically stored in
	 * the DAR, but not the MD_EPN register.  We must copy the 20 most
	 * significant bits of the EA from the DAR to MD_EPN before we
	 * start walking the page tables.  We also need to copy the CASID
	 * value from the M_CASID register.
	 * Addendum:  The EA of a data TLB error is _supposed_ to be stored
	 * in DAR, but it seems that this doesn't happen in some cases, such
	 * as when the error is due to a dcbi instruction to a page with a
	 * TLB that doesn't have the changed bit set.  In such cases, there
	 * does not appear to be any way  to recover the EA of the error
	 * since it is neither in DAR nor MD_EPN.  As a workaround, the
	 * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs
	 * are initialized in mapin_ram().  This will avoid the problem,
	 * assuming we only use the dcbi instruction on kernel addresses.
	 */

	/* DAR is in r10 already */
	rlwinm	r11, r10, 0, 0, 19
	ori	r11, r11, MD_EVALID
	mfspr	r10, SPRN_M_CASID
	rlwimi	r11, r10, 0, 28, 31
	DO_8xx_CPU6(0x3780, r3)
	mtspr	SPRN_MD_EPN, r11

	mfspr	r10, SPRN_M_TWB	/* Get level 1 table entry address */

	/* If we are faulting a kernel address, we have to use the
	 * kernel page tables.
	 */
	andi.	r11, r10, 0x0800
	beq	3f
	lis	r11, swapper_pg_dir@h
	ori	r11, r11, swapper_pg_dir@l
	rlwimi	r10, r11, 0, 2, 19
3:
	lwz	r11, 0(r10)	/* Get the level 1 entry */
	rlwinm.	r10, r11,0,0,19	/* Extract page descriptor page address */
	beq	2f		/* If zero, bail */

	/* We have a pte table, so fetch the pte from the table.
	 */
	ori	r11, r11, 1		/* Set valid bit in physical L2 page */
	DO_8xx_CPU6(0x3b80, r3)
	mtspr	SPRN_MD_TWC, r11	/* Load pte table base address */
	mfspr	r10, SPRN_MD_TWC	/* ....and get the pte address */
	lwz	r10, 0(r10)		/* Get the pte */
	/* Insert the Guarded flag into the TWC from the Linux PTE.
	 * It is bit 27 of both the Linux PTE and the TWC
	 */
	rlwimi	r11, r10, 0, 27, 27
	/* Insert the WriteThru flag into the TWC from the Linux PTE.
	 * It is bit 25 in the Linux PTE and bit 30 in the TWC
	 */
	rlwimi	r11, r10, 32-5, 30, 30
	DO_8xx_CPU6(0x3b80, r3)
	mtspr	SPRN_MD_TWC, r11
	mfspr	r11, SPRN_MD_TWC	/* get the pte address again */

	ori	r10, r10, _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HWWRITE
	stw	r10, 0(r11)		/* and update pte in table */
	xori	r10, r10, _PAGE_RW	/* RW bit is inverted */

	/* The Linux PTE won't go exactly into the MMU TLB.
	 * Software indicator bits 22 and 28 must be clear.
	 * Software indicator bits 24, 25, 26, and 27 must be
	 * set.  All other Linux PTE bits control the behavior
	 * of the MMU.
	 */
	li	r11, 0x00f0
	mtspr	SPRN_DAR,r11	/* Tag DAR */
	rlwimi	r10, r11, 0, 24, 28	/* Set 24-27, clear 28 */
	DO_8xx_CPU6(0x3d80, r3)
	mtspr	SPRN_MD_RPN, r10	/* Update TLB entry */

	mfspr	r10, SPRN_M_TW	/* Restore registers */
	lwz	r11, 0(r0)
	mtcr	r11
	lwz	r11, 4(r0)
#ifdef CONFIG_8xx_CPU6
	lwz	r3, 8(r0)
#endif
	rfi
2:
	mfspr	r10, SPRN_M_TW	/* Restore registers */
	lwz	r11, 0(r0)
	mtcr	r11