[BACK]Return to copy_subr.S CVS log [TXT][DIR] Up to [local] / sys / lib / libkern / arch / m88k

File: [local] / sys / lib / libkern / arch / m88k / copy_subr.S (download)

Revision 1.1.1.1 (vendor branch), Tue Mar 4 16:15:13 2008 UTC (16 years, 3 months ago) by nbrk
Branch: OPENBSD_4_2_BASE, MAIN
CVS Tags: jornada-partial-support-wip, HEAD
Changes since 1.1: +0 -0 lines

Import of OpenBSD 4.2 release kernel tree with initial code to support 
Jornada 720/728, StrongARM 1110-based handheld PC.
At this point kernel roots on NFS and boots into vfs_mountroot() and traps.
What is supported:
- glass console, Jornada framebuffer (jfb) works in 16bpp direct color mode
(needs some palette tweaks for non black/white/blue colors, i think)
- saic, SA11x0 interrupt controller (needs cleanup)
- sacom, SA11x0 UART (supported only as boot console for now)
- SA11x0 GPIO controller fully supported (but can't handle multiple interrupt
handlers on one gpio pin)
- sassp, SSP port on SA11x0 that attaches spibus
- Jornada microcontroller (jmcu) to control kbd, battery, etc throught
the SPI bus (wskbd attaches on jmcu, but not tested)
- tod functions seem work
- initial code for SA-1111 (chip companion) : this is TODO

Next important steps, i think:
- gpio and intc on sa1111
- pcmcia support for sa11x0 (and sa1111 help logic)
- REAL root on nfs when we have PCMCIA support (we may use any of supported pccard NICs)
- root on wd0! (using already supported PCMCIA-ATA)

/*	$OpenBSD: copy_subr.S,v 1.1 2006/11/17 22:32:38 miod Exp $	*/
/*
 * Mach Operating System
 * Copyright (c) 1993-1992 Carnegie Mellon University
 * Copyright (c) 1991 OMRON Corporation
 * Copyright (c) 1996 Nivas Madhur
 * Copyright (c) 1998 Steve Murphree, Jr.
 * All Rights Reserved.
 *
 * Permission to use, copy, modify and distribute this software and its
 * documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie the
 * rights to redistribute these changes.
 */

#include <machine/asm.h>

/*
 * copy count bytes of data from source to destination
 * Don Harper (don@omron.co.jp), Omron Corporation.
 */

#if defined(MEMCPY) || defined(MEMMOVE)
#define	SRC	r3
#define	DST	r2
#define	SAVE	r5
#else
#define	SRC	r2
#define	DST	r3
#endif
#define	LEN	r4

#ifdef MEMCPY
ENTRY(memcpy)
#endif
#ifdef MEMMOVE
ENTRY(memmove)
#endif
#ifdef BCOPY
ENTRY(bcopy)
#endif
#ifdef OVBCOPY
ENTRY(ovbcopy)
#endif

#if defined(MEMCPY) || defined(MEMMOVE)
	or	SAVE, DST, r0
#endif

	bcnd	eq0,LEN,_ASM_LABEL(bcopy_out)	/* nothing to do if == 0 */

/*
 * check position of source and destination data
 */
	cmp 	r9,SRC,DST	/* compare source address to destination */
	bb1	eq,r9,_ASM_LABEL(bcopy_out)	/* nothing to do if equal */
#if defined(MEMMOVE) || defined(OVBCOPY)
	bb1	lo,r9,_ASM_LABEL(bcopy_reverse)	/* reverse copy if src < dest */
#endif

/*
 * source address is greater than destination address, or we do
 * not have to care about overlapping areas: copy forward
 */
	cmp 	r9,LEN,16	/* see if we have at least 16 bytes */
	bb1	lt,r9,_ASM_LABEL(f_byte_copy)	/* copy bytes for small data length */
/*
 * determine copy strategy based on alignment of source and destination
 */
	mask	r6,SRC,3	/* get 2 low order bits of source address */
	mask	r7,DST,3	/* get 2 low order bits of destintation addr */
	mak	r6,r6,0<4>	/* convert source bits to table offset */
	mak	r7,r7,0<2>	/* convert destination bits to table offset */
	or.u	r12,r0,hi16(_ASM_LABEL(f_strat))
	or	r12,r12,lo16(_ASM_LABEL(f_strat))
	addu	r6,r6,r7	/* compute final table offset for strategy */
	ld	r12,r12,r6	/* load the strategy routine */
	jmp	r12		/* branch to strategy routine */

/*
 * Copy three bytes from src to destination then copy words
 */
ASLOCAL(f_3byte_word_copy)
	ld.bu	r6,SRC,0	/* load byte from source */
	ld.bu	r7,SRC,1	/* load byte from source */
	ld.bu	r8,SRC,2	/* load byte from source */
	st.b	r6,DST,0	/* store byte to destination */
	st.b	r7,DST,1	/* store byte to destination */
	st.b	r8,DST,2	/* store byte to destination */
	addu	SRC,SRC,3	/* increment source pointer */
	addu	DST,DST,3	/* increment destination pointer */
	br.n	_ASM_LABEL(f_word_copy)	/* copy full words */
	 subu	LEN,LEN,3	/* decrement length */

/*
 * Copy 1 halfword from src to destination then copy words
 */
ASLOCAL(f_1half_word_copy)
	ld.hu	r6,SRC,0	/* load half-word from source */
	st.h	r6,DST,0	/* store half-word to destination */
	addu	SRC,SRC,2	/* increment source pointer */
	addu	DST,DST,2	/* increment destination pointer */
	br.n	_ASM_LABEL(f_word_copy)	/* copy full words */
	 subu	LEN,LEN,2	/* decrement remaining length */

/*
 * Copy 1 byte from src to destination then copy words
 */
ASLOCAL(f_1byte_word_copy)
	ld.bu	r6,SRC,0	/* load 1 byte from source */
	st.b	r6,DST,0	/* store 1 byte to destination */
	addu	SRC,SRC,1	/* increment source pointer */
	addu	DST,DST,1	/* increment destination pointer */
	subu	LEN,LEN,1	/* decrement remaining length */
	/* FALLTHROUGH */
/*
 * Copy as many full words as possible, 4 words per loop
 */
ASLOCAL(f_word_copy)
	cmp	r10,LEN,16	/* see if we have 16 bytes remaining */
	bb1	lo,r10,_ASM_LABEL(f_byte_copy)	/* not enough left, copy bytes */
	ld	r6,SRC,0	/* load first word */
	ld	r7,SRC,4	/* load second word */
	ld	r8,SRC,8	/* load third word */
	ld	r9,SRC,12	/* load fourth word */
	st	r6,DST,0	/* store first word */
	st	r7,DST,4	/* store second word */
	st 	r8,DST,8	/* store third word */
	st 	r9,DST,12	/* store fourth word */
	addu	SRC,SRC,16	/* increment source pointer */
	addu	DST,DST,16	/* increment destination pointer */
	br.n	_ASM_LABEL(f_word_copy)	/* branch to copy another block */
	 subu	LEN,LEN,16	/* decrement remaining length */

ASLOCAL(f_1byte_half_copy)
	ld.bu	r6,SRC,0	/* load 1 byte from source */
	st.b	r6,DST,0	/* store 1 byte to destination */
	addu	SRC,SRC,1	/* increment source pointer */
	addu	DST,DST,1	/* increment destination pointer */
	subu	LEN,LEN,1	/* decrement remaining length */
	/* FALLTHROUGH */

ASLOCAL(f_half_copy)
	cmp	r10,LEN,16	/* see if we have 16 bytes remaining */
	bb1	lo,r10,_ASM_LABEL(f_byte_copy)	/* not enough left, copy bytes */
	ld.hu	r6,SRC,0	/* load first half-word */
	ld.hu	r7,SRC,2	/* load second half-word */
	ld.hu	r8,SRC,4	/* load third half-word */
	ld.hu	r9,SRC,6	/* load fourth half-word */
	ld.hu	r10,SRC,8	/* load fifth half-word */
	ld.hu	r11,SRC,10	/* load sixth half-word */
	ld.hu	r12,SRC,12	/* load seventh half-word */
	ld.hu	r13,SRC,14	/* load eighth half-word */
	st.h	r6,DST,0	/* store first half-word */
	st.h	r7,DST,2	/* store second half-word */
	st.h 	r8,DST,4	/* store third half-word */
	st.h 	r9,DST,6	/* store fourth half-word */
	st.h	r10,DST,8	/* store fifth half-word */
	st.h	r11,DST,10	/* store sixth half-word */
	st.h 	r12,DST,12	/* store seventh half-word */
	st.h 	r13,DST,14	/* store eighth half-word */
	addu	SRC,SRC,16	/* increment source pointer */
	addu	DST,DST,16	/* increment destination pointer */
	br.n	_ASM_LABEL(f_half_copy)	/* branch to copy another block */
	 subu	LEN,LEN,16	/* decrement remaining length */

ASLOCAL(f_byte_copy)
	bcnd	eq0,LEN,_ASM_LABEL(bcopy_out)	/* branch if nothing left to copy */
	ld.bu	r6,SRC,0	/* load byte from source */
	st.b	r6,DST,0	/* store byte in destination */
	addu	SRC,SRC,1	/* increment source pointer */
	addu	DST,DST,1	/* increment destination pointer */
	br.n	_ASM_LABEL(f_byte_copy)	/* branch for next byte */
	 subu	LEN,LEN,1	/* decrement remaining length */

#if defined(MEMMOVE) || defined(OVBCOPY)
/*
 * source address is less than destination address, copy in reverse
 */
ASLOCAL(bcopy_reverse)
/*
 * start copy pointers at end of data
 */
	addu	SRC,SRC,LEN	/* start source at end of data */
	addu	DST,DST,LEN	/* start destination at end of data */
/*
 * check for short data
 */
	cmp 	r9,LEN,16	/* see if we have at least 16 bytes */
	bb1	lt,r9,_ASM_LABEL(r_byte_copy)	/* copy bytes for small data length */
/*
 *	determine copy strategy based on alignment of source and destination
 */
	mask	r6,SRC,3	/* get 2 low order bits of source address */
	mask	r7,DST,3	/* get 2 low order bits of destintation addr */
	mak	r6,r6,0<4>	/* convert source bits to table offset */
	mak	r7,r7,0<2>	/* convert destination bits to table offset */
	or.u	r12,r0,hi16(_ASM_LABEL(r_strat))
	or	r12,r12,lo16(_ASM_LABEL(r_strat))
	addu	r6,r6,r7	/* compute final table offset for strategy */
	ld	r12,r12,r6	/* load the strategy routine */
	jmp	r12		/* branch to strategy routine */

/*
 * Copy three bytes from src to destination then copy words
 */
ASLOCAL(r_3byte_word_copy)
	subu	SRC,SRC,3	/* decrement source pointer */
	subu	DST,DST,3	/* decrement destination pointer */
	ld.bu	r6,SRC,0	/* load byte from source */
	ld.bu	r7,SRC,1	/* load byte from source */
	ld.bu	r8,SRC,2	/* load byte from source */
	st.b	r6,DST,0	/* store byte to destination */
	st.b	r7,DST,1	/* store byte to destination */
	st.b	r8,DST,2	/* store byte to destination */
	br.n	_ASM_LABEL(r_word_copy)	/* copy full words */
	 subu	LEN,LEN,3	/* decrement length */

/*
 * Copy 1 halfword from src to destination then copy words
 */
ASLOCAL(r_1half_word_copy)
	subu	SRC,SRC,2	/* decrement source pointer */
	subu	DST,DST,2	/* decrement destination pointer */
	ld.hu	r6,SRC,0	/* load half-word from source */
	st.h	r6,DST,0	/* store half-word to destination */
	br.n	_ASM_LABEL(r_word_copy)	/* copy full words */
	 subu	LEN,LEN,2	/* decrement remaining length */

/*
 * Copy 1 byte from src to destination then copy words
 */
ASLOCAL(r_1byte_word_copy)
	subu	SRC,SRC,1	/* decrement source pointer */
	subu	DST,DST,1	/* decrement destination pointer */
	ld.bu	r6,SRC,0	/* load 1 byte from source */
	st.b	r6,DST,0	/* store 1 byte to destination */
	subu	LEN,LEN,1	/* decrement remaining length */
	/* FALLTHROUGH */
/*
 * Copy as many full words as possible, 4 words per loop
 */
ASLOCAL(r_word_copy)
	cmp	r10,LEN,16	/* see if we have 16 bytes remaining */
	bb1	lo,r10,_ASM_LABEL(r_byte_copy)	/* not enough left, copy bytes */
	subu	SRC,SRC,16	/* decrement source pointer */
	subu	DST,DST,16	/* decrement destination pointer */
	ld	r6,SRC,0	/* load first word */
	ld	r7,SRC,4	/* load second word */
	ld	r8,SRC,8	/* load third word */
	ld	r9,SRC,12	/* load fourth word */
	st	r6,DST,0	/* store first word */
	st	r7,DST,4	/* store second word */
	st 	r8,DST,8	/* store third word */
	st 	r9,DST,12	/* store fourth word */
	br.n	_ASM_LABEL(r_word_copy)	/* branch to copy another block */
	 subu	LEN,LEN,16	/* decrement remaining length */

ASLOCAL(r_1byte_half_copy)
	subu	SRC,SRC,1	/* decrement source pointer */
	subu	DST,DST,1	/* decrement destination pointer */
	ld.bu	r6,SRC,0	/* load 1 byte from source */
	st.b	r6,DST,0	/* store 1 byte to destination */
	subu	LEN,LEN,1	/* decrement remaining length */
	/* FALLTHROUGH */

ASLOCAL(r_half_copy)
	cmp	r10,LEN,16	/* see if we have 16 bytes remaining */
	bb1	lo,r10,_ASM_LABEL(r_byte_copy)	/* not enough left, copy bytes */
	subu	SRC,SRC,16	/* decrement source pointer */
	subu	DST,DST,16	/* decrement destination pointer */
	ld.hu	r6,SRC,0	/* load first half-word */
	ld.hu	r7,SRC,2	/* load second half-word */
	ld.hu	r8,SRC,4	/* load third half-word */
	ld.hu	r9,SRC,6	/* load fourth half-word */
	ld.hu	r10,SRC,8	/* load fifth half-word */
	ld.hu	r11,SRC,10	/* load sixth half-word */
	ld.hu	r12,SRC,12	/* load seventh half-word */
	ld.hu	r13,SRC,14	/* load eighth half-word */
	st.h	r6,DST,0	/* store first half-word */
	st.h	r7,DST,2	/* store second half-word */
	st.h 	r8,DST,4	/* store third half-word */
	st.h 	r9,DST,6	/* store fourth half-word */
	st.h	r10,DST,8	/* store fifth half-word */
	st.h	r11,DST,10	/* store sixth half-word */
	st.h 	r12,DST,12	/* store seventh half-word */
	st.h 	r13,DST,14	/* store eighth half-word */
	br.n	_ASM_LABEL(r_half_copy)	/* branch to copy another block */
	 subu	LEN,LEN,16	/* decrement remaining length */

ASLOCAL(r_byte_copy)
	bcnd	eq0,LEN,_ASM_LABEL(bcopy_out)	/* branch if nothing left to copy */
	subu	SRC,SRC,1		/* decrement source pointer */
	subu	DST,DST,1		/* decrement destination pointer */
	ld.bu	r6,SRC,0		/* load byte from source */
	st.b	r6,DST,0		/* store byte in destination */
	br.n	_ASM_LABEL(r_byte_copy)	/* branch for next byte */
	 subu	LEN,LEN,1		/* decrement remaining length */
#endif	/* MEMMOVE || OVBCOPY */

ASLOCAL(bcopy_out)
#if defined(MEMCPY) || defined(MEMMOVE)
	jmp.n	r1		/* all done, return to caller */
	 or	r2, SAVE, r0
#else
	jmp	r1		/* all done, return to caller */
#endif

	data
	align	4
ASLOCAL(f_strat)
	word	_ASM_LABEL(f_word_copy)
	word	_ASM_LABEL(f_byte_copy)
	word	_ASM_LABEL(f_half_copy)
	word	_ASM_LABEL(f_byte_copy)
	word	_ASM_LABEL(f_byte_copy)
	word	_ASM_LABEL(f_3byte_word_copy)
	word	_ASM_LABEL(f_byte_copy)
	word	_ASM_LABEL(f_1byte_half_copy)
	word	_ASM_LABEL(f_half_copy)
	word	_ASM_LABEL(f_byte_copy)
	word	_ASM_LABEL(f_1half_word_copy)
	word	_ASM_LABEL(f_byte_copy)
	word	_ASM_LABEL(f_byte_copy)
	word	_ASM_LABEL(f_1byte_half_copy)
	word	_ASM_LABEL(f_byte_copy)
	word	_ASM_LABEL(f_1byte_word_copy)

#if defined(MEMMOVE) || defined(OVBCOPY)
ASLOCAL(r_strat)
	word	_ASM_LABEL(r_word_copy)
	word	_ASM_LABEL(r_byte_copy)
	word	_ASM_LABEL(r_half_copy)
	word	_ASM_LABEL(r_byte_copy)
	word	_ASM_LABEL(r_byte_copy)
	word	_ASM_LABEL(r_1byte_word_copy)
	word	_ASM_LABEL(r_byte_copy)
	word	_ASM_LABEL(r_1byte_half_copy)
	word	_ASM_LABEL(r_half_copy)
	word	_ASM_LABEL(r_byte_copy)
	word	_ASM_LABEL(r_1half_word_copy)
	word	_ASM_LABEL(r_byte_copy)
	word	_ASM_LABEL(r_byte_copy)
	word	_ASM_LABEL(r_1byte_half_copy)
	word	_ASM_LABEL(r_byte_copy)
	word	_ASM_LABEL(r_3byte_word_copy)
#endif