Source to machdep/ppc/movc.s


Enter a symbol's name here to quickly find it.

/*
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
 * Reserved.  This file contains Original Code and/or Modifications of
 * Original Code as defined in and that are subject to the Apple Public
 * Source License Version 1.0 (the 'License').  You may not use this file
 * except in compliance with the License.  Please obtain a copy of the
 * License at http://www.apple.com/publicsource and read it before using
 * this file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License."
 * 
 * @APPLE_LICENSE_HEADER_END@
 */

/*
 * HISTORY
 * Revision 1.2  1997/10/29 02:14:00  tmason
 * Fixed oodles of bugs related to pmap issues as well as bcopy, FLOAT!, and cached accesses.
 * Radar Bug ID:
 *
 * Revision 1.1.1.1  1997/09/30 02:45:23  wsanchez
 * Import of kernel from umeshv/kernel
 *
 * Revision 1.1.??.1  1997/06/28  10:58:00  rvega
 *	Radar #1665906
 * 	Restore comments, alignment, and white space lost during integration.
 * 	[1997/06/28  10:58:00  rvega]
 *
 * Revision 1.1.??.1  1997/06/17  14:54:28  rvega
 * 	pmap_page_copy needs to flush the i-cache *and*
 *	it needs to work without using floating point registers.
 * 	[1997/06/17  14:54:28  rvega]
 *
 * Revision 1.1.??.1  1997/05/14  18:55:55  rvega
 * 	Cleanup sync/isync usage.
 * 	[1997/05/14  18:55:55  rvega]
 *
 */
 
/*
 * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991  
 *              All Rights Reserved 
 *  
 * Permission to use, copy, modify, and distribute this software and 
 * its documentation for any purpose and without fee is hereby granted, 
 * provided that the above copyright notice appears in all copies and 
 * that both the copyright notice and this permission notice appear in 
 * supporting documentation. 
 *  
 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 * FOR A PARTICULAR PURPOSE. 
 *  
 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
 */
/*
 * MKLINUX-1.0DR2
 */

#include <debug.h>
#include <ppc/asm.h>
#include <ppc/proc_reg.h>
#include <mach/ppc/vm_param.h>
#include <assym.h>

#ifndef USE_FLOATING_POINT_IN_KERNEL
#define	USE_FLOATING_POINT_IN_KERNEL	0
#else
#undef USE_FLOATING_POINT_IN_KERNEL
#define	USE_FLOATING_POINT_IN_KERNEL	0
#endif


/*
 * void pmap_zero_page(vm_offset_t pa)
 *
 * zero a page of physical memory.
 */

#if DEBUG
	/* C debug stub in pmap.c calls this */
ENTRY(pmap_zero_page_assembler, TAG_NO_FRAME_USED)
#else
ENTRY(pmap_zero_page, TAG_NO_FRAME_USED)
#endif /* DEBUG */

	/* Switch off data translations */
	mfmsr	r6
	rlwinm	r7,	r6,	0,	MSR_DR_BIT+1,	MSR_DR_BIT-1
	mtmsr	r7
	isync			/* Ensure data translations are off */

#ifndef UNCACHED_DATA_604
	li	r4, (PPC_PGBYTES/CACHE_LINE_SIZE)
#else	/* UNCACHED_DATA_604 */
	li	r4, (PPC_PGBYTES/4)
#endif	/* UNCACHED_DATA_604 */
	mtctr	r4
.L_phys_zero_loop:	
#ifndef UNCACHED_DATA_604
	dcbz	0, ARG0
	addi	ARG0, ARG0, CACHE_LINE_SIZE
#else	/* UNCACHED_DATA_604 */
	li	r7, 0
	stwx	r7, 0, ARG0
	addi	ARG0, ARG0, 4
#endif	/* UNCACHED_DATA_604 */
	bdnz+	.L_phys_zero_loop

	sync			/* Finish any outstanding writes */
	mtmsr	r6		/* Restore original translations */
	isync			/* Ensure data translations are on */

	blr

/* void
 * phys_copy(src, dst, bytecount)
 *      vm_offset_t     src;
 *      vm_offset_t     dst;
 *      int             bytecount
 *
 * This routine will copy bytecount bytes from physical address src to physical
 * address dst. 
 */

ENTRY(phys_copy, TAG_NO_FRAME_USED)

	/* Switch off data relocation.
	*/
	mfmsr	r6
	rlwinm	r7,	r6,	0,	MSR_DR_BIT+1,	MSR_DR_BIT-1
	mtmsr	r7
	isync			/* Ensure data translations are off */
	mtctr	ARG2
.L_phys_copy_byte_loop:	
	lbz	r7, 0(ARG0)
	stb	r7, 0(ARG1)
	addi	ARG0, ARG0, 1
	addi	ARG1, ARG1, 1
	bdnz+	.L_phys_copy_byte_loop

.L_phys_copy_done:
	mtmsr	r6		/* Restore original translations */
	isync			/* Ensure data translations are off */

	blr




/* void
 * pmap_copy_page(src, dst)
 *      vm_offset_t     src;
 *      vm_offset_t     dst;
 *
 * This routine will copy the physical page src to physical page dst
 * 
 * This routine assumes that the src and dst are page aligned and that the
 * destination is cached.
 *
 * This routine is called in a myriad places to copy pages containing
 * instructions to be executed later, therefore it has to invalidate the
 * i-cache entries of the destination page.
 */

#if DEBUG
	/* if debug, we have a little piece of C around this
	 * in pmap.c that gives some trace ability
	 */
ENTRY(pmap_copy_page_assembler, TAG_NO_FRAME_USED)
#else
ENTRY(pmap_copy_page, TAG_NO_FRAME_USED)
#endif /* DEBUG */

#if USE_FLOATING_POINT_IN_KERNEL
	/* Save off the link register, we want to call fpu_save. We assume
	 * that fpu_save leaves ARG0-5 intact and that it doesn't need
	 * a frame, otherwise we'd need one too.
	 */
	
	mflr	ARG3
	bl	EXT(fpu_save)
	mtlr	ARG3
#endif /* USE_FLOATING_POINT_IN_KERNEL */

	/* Switch off data relocation.
	*/
	mfmsr	r6
	rlwinm	r7,	r6,	0,	MSR_DR_BIT+1,	MSR_DR_BIT-1
	mtmsr	r7
	isync			/* Ensure data translations are off */

#if USE_FLOATING_POINT_IN_KERNEL
	li	r7,	(PPC_PGBYTES/(2*32))
	mtctr	r7
	li	r7, 32
#else /* USE_FLOATING_POINT_IN_KERNEL */
	li	r7,	(PPC_PGBYTES/CACHE_LINE_SIZE)
	mtctr	r7
#endif /* USE_FLOATING_POINT_IN_KERNEL */

.L_pmap_copy_page_loop:
#ifndef	UNCACHED_DATA_604
	dcbz	0,	ARG1
#if USE_FLOATING_POINT_IN_KERNEL
	dcbz	r7,	ARG1
#endif /* USE_FLOATING_POINT_IN_KERNEL */
#endif	/* UNCACHED_DATA_604 */

#if USE_FLOATING_POINT_IN_KERNEL
	lfd	f0,  0(ARG0)
	lfd	f1,  8(ARG0)
	lfd	f2, 16(ARG0)
	lfd	f3, 24(ARG0)
	lfd	f4, 32(ARG0)
	lfd	f5, 40(ARG0)
	lfd	f6, 48(ARG0)
	lfd	f7, 56(ARG0)
	addi	ARG0,	ARG0,	(2*32)

	stfd	f0,  0(ARG1)
	stfd	f1,  8(ARG1)
	stfd	f2, 16(ARG1)
	stfd	f3, 24(ARG1)
#ifndef	UNCACHED_DATA_604
	dcbst	0,	ARG1
	sync
#endif	/* UNCACHED_DATA_604 */
#ifndef	UNCACHED_INST_604
	icbi	0,	ARG1
	sync
	isync
#endif	/* UNCACHED_INST_604 */

	addi	ARG1,	ARG1,	CACHE_LINE_SIZE

	stfd	f4,  0(ARG1)
	stfd	f5,  8(ARG1)
	stfd	f6, 16(ARG1)
	stfd	f7, 24(ARG1)
#else USE_FLOATING_POINT_IN_KERNEL
	lwz	r0,   0(ARG0)
	lwz	r5,   4(ARG0)
	lwz	r7,   8(ARG0)
	lwz	r8,  12(ARG0)
	lwz	r9,  16(ARG0)
	lwz	r10, 20(ARG0)
	lwz	r11, 24(ARG0)
	lwz	r12, 28(ARG0)
	addi	ARG0,	ARG0,	CACHE_LINE_SIZE

	stw	r0,   0(ARG1)
	stw	r5,   4(ARG1)
	stw	r7,   8(ARG1)
	stw	r8,  12(ARG1)
	stw	r9,  16(ARG1)
	stw	r10, 20(ARG1)
	stw	r11, 24(ARG1)
	stw	r12, 28(ARG1)

#endif /* USE_FLOATING_POINT_IN_KERNEL */

	/*
	**	Invalidate the i-cache entries.
	*/
#ifndef	UNCACHED_DATA_604
	dcbst	0,	ARG1
	sync
#endif	/* UNCACHED_DATA_604 */
#ifndef	UNCACHED_INST_604
	icbi	0,	ARG1
	sync
	isync
#endif	/* UNCACHED_INST_604 */

	addi	ARG1,	ARG1,	CACHE_LINE_SIZE
	bdnz+	.L_pmap_copy_page_loop

#if	USE_FLOATING_POINT_IN_KERNEL
	rlwinm	r6,	r6,	0,	MSR_FP_BIT+1,	MSR_FP_BIT-1
#endif /* USE_FLOATING_POINT_IN_KERNEL */
	mtmsr	r6		/* Restore original translations */
	isync			/* Ensure data translations are on */

	blr



/*
 * vm_offset_t
 * view_user_address(addr)
 *	vm_offset_t	addr;
 *
 * Set SR_COPYIN to point to segmentt containing address
 * and return modified address.
 * 
 */

ENTRY(view_user_address, TAG_NO_FRAME_USED)
	addis	ARG1,	0,	ha16(EXT(kdp_space))
	addi	ARG1,	ARG1,	lo16(EXT(kdp_space))
	lwz	ARG1,	0(ARG1)
	cmpwi	ARG1,	0		; if kdp_space is set use that
	bne	1f
	mfsprg	ARG1,	0	/* get per-proc_info */
	lwz	ARG1,	PP_CPU_DATA(ARG1)
	lwz	ARG1,	CPU_ACTIVE_THREAD(ARG1)
	lwz	ARG1,	THREAD_TASK(ARG1)
	lwz	ARG1,	TASK_VMMAP(ARG1)
	lwz	ARG1,	VMMAP_PMAP(ARG1)
	lwz	ARG1,	PMAP_SPACE(ARG1)
1:
	lis	r0,	SEG_REG_PROT>>16	/* Top byte of SR value */
	rlwimi	r0,	ARG1,	4,	4,	31 /* Insert space<<4   */
	rlwimi	r0,	ARG0,	4,	28,	31 /* Insert seg number */

	isync
	mtsr	SR_COPYIN_NAME,	r0
	isync

	/* ARG0 = adjusted user pointer mapping into SR_COPYIN */
	rlwinm	ARG0,	ARG0,	0,	4,	31
	oris	ARG0,	ARG0,	(SR_COPYIN << (28-16))

	blr

ENTRY(cioseg, TAG_NO_FRAME_USED)
	// build seg reg value
	lis	r7,	SEG_REG_PROT>>16	/* Top byte of SR value */
	rlwimi	r7,	r3,	4,	4,	31 /* Insert space<<4   */
	rlwimi	r7,	r4,	4,	28,	31 /* Insert seg number */

	// update seg reg
	isync
	mtsr	SR_COPYIN_NAME,	r7
	isync

	// build and return mapped addr for caller
	rlwinm	r3,	r4,	0,	4,	31
	oris	r3,	r3,	(SR_COPYIN << (28-16))

	blr