svn commit: r297537 - head/sys/arm64/arm64

Wojciech Macek wma at FreeBSD.org
Mon Apr 4 07:11:34 UTC 2016


Author: wma
Date: Mon Apr  4 07:11:33 2016
New Revision: 297537
URL: https://svnweb.freebsd.org/changeset/base/297537

Log:
  Add bzero.S to ARM64 machdep
  
  Add fille missing from https://svnweb.freebsd.org/changeset/base/297536

Added:
  head/sys/arm64/arm64/bzero.S   (contents, props changed)

Added: head/sys/arm64/arm64/bzero.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm64/arm64/bzero.S	Mon Apr  4 07:11:33 2016	(r297537)
@@ -0,0 +1,206 @@
+/*-
+ * Copyright (C) 2016 Cavium Inc.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+
+#include "assym.s"
+
+	/*
+	 * void bzero(void *p, size_t size)
+	 *
+	 *  x0 - p
+	 *  x1 - size
+	 */
+ENTRY(bzero)
+	cbz	x1, ending
+
+	/*
+	 * x5 is number of cache lines to zero - calculated later and
+	 * will become non-zero if  buffer is long enough to zero by
+	 * cache lines (and if it is allowed.)
+	 * We need to zero it before proceeding with buffers of size
+	 * smaller than 16 bytes - otherwise the x5 will not be
+	 * calculated and will retain random value.
+	 * "normal" is used for buffers <= 16 bytes and to align buffer
+	 * to cache line for buffers bigger than cache line; non-0 x5
+	 * after "normal" has completed indicates that it has been used
+	 * to align buffer to cache line and now zero by cache lines will
+	 * be performed, and x5 is amount of cache lines to loop through.
+	 */
+	mov	x5, xzr
+
+	/* No use of cache assisted zero for buffers with size <= 16 */
+	cmp	x1, #0x10
+	b.le	normal
+
+	/*
+	 * Load size of line that will be cleaned by dc zva call.
+	 * 0 means that the instruction is not allowed
+	 */
+	ldr	x7, =dczva_line_size
+	ldr	x7, [x7]
+	cbz	x7, normal
+
+	/*
+	 * Buffer must be larger than cache line for using cache zeroing
+	 * (and cache line aligned but this is checked after jump)
+	 */
+	cmp	x1, x7
+	b.lt	normal
+
+	/*
+	 * Calculate number of bytes to cache aligned address (x4) nad
+	 * number of full cache lines (x5). x6 is final address to zero.
+	 */
+	sub	x2, x7, #0x01
+	mov	x3, -1
+	eor	x3, x3, x2
+	add	x4, x0, x2
+	and	x4, x4, x3
+	subs	x4, x4, x0
+	b.eq	normal
+
+	/* Calculate number of "lines" in buffer */
+	sub	x5, x1, x4
+	rbit	x2, x7
+	clz	x2, x2
+	lsr	x5, x5, x2
+
+	/*
+	 * If number of cache lines is 0, we will not be able to zero
+	 * by cache lines, so go normal way.
+	 */
+	cbz	x5, normal
+	/* x6 is final address to zero */
+	add	x6, x0, x1
+
+	/*
+	 * We are here because x5 is non-0 so normal will be used to
+	 * align buffer before cache zeroing. x4 holds number of bytes
+	 * needed for alignment.
+	 */
+	mov	x1, x4
+
+	/* When jumping here: x0 holds pointer, x1 holds size */
+normal:
+	/*
+	 * Get buffer offset into 16 byte aligned address; 0 means pointer
+	 * is aligned.
+	 */
+	ands	x2, x0, #0x0f
+	b.eq	aligned_to_16
+	/* Calculate one-byte loop runs to 8 byte aligned address. */
+	ands	x2, x2, #0x07
+	mov	x3, #0x08
+	sub	x2, x3, x2
+	/* x2 is number of bytes missing for alignment, x1 is buffer size */
+	cmp	x1, x2
+	csel	x2, x1, x2, le
+	sub	x1, x1, x2
+
+	/*
+	 * Byte by byte copy will copy at least enough bytes to align
+	 * pointer and at most "size".
+	 */
+align:
+	strb	wzr, [x0], #0x01
+	subs	x2, x2, #0x01
+	b.ne	align
+
+	/* Now pointer is aligned to 8 bytes */
+	cmp	x1, #0x10
+	b.lt	lead_out
+	/* 
+	 * Check if copy of another 8 bytes is needed to align to 16 byte
+	 * address and do it
+	 */
+	tbz	x0, #0x03, aligned_to_16
+	str	xzr, [x0], #0x08
+	sub	x1, x1, #0x08
+
+	/* While jumping here: x0 is 16 byte alligned address, x1 is size */
+aligned_to_16:
+	/* If size is less than 16 bytes, use lead_out to copy what remains */
+	cmp	x1, #0x10
+	b.lt	lead_out
+
+	lsr	x2, x1, #0x04
+zero_by_16:
+	stp	xzr, xzr, [x0], #0x10
+	subs	x2, x2, #0x01
+	b.ne	zero_by_16
+
+	/*
+	 * Lead out requires addresses to be aligned to 8 bytes. It is used to
+	 * zero buffers with sizes < 16 and what can not be zeroed by
+	 * zero_by_16 loop.
+	 */
+	ands	x1, x1, #0x0f
+	b.eq	lead_out_end
+lead_out:
+	tbz	x1, #0x03, lead_out_dword
+	str	xzr, [x0], #0x08
+lead_out_dword:
+	tbz	x1, #0x02, lead_out_word
+	str	wzr, [x0], #0x04
+lead_out_word:
+	tbz	x1, #0x01, lead_out_byte
+	strh	wzr, [x0], #0x02
+lead_out_byte:
+	tbz	x1, #0x00, lead_out_end
+	strb	wzr, [x0], #0x01
+
+lead_out_end:
+	/*
+	 * If x5 is non-zero, this means that normal has been used as
+	 * a lead in to align buffer address to cache size
+	 */
+	cbz	x5, ending
+
+	/*
+	 * Here x5 holds number of lines to zero; x6 is final address of
+	 * buffer. x0 is cache line aligned pointer. x7 is cache line size
+	 * in bytes
+	 */
+cache_line_zero:
+	dc	zva, x0
+	add	x0, x0, x7
+	subs	x5, x5, #0x01
+	b.ne	cache_line_zero
+
+	/* Need to zero remaining bytes? */
+	subs	x1, x6, x0
+	b.ne	normal
+
+ending:
+	ret
+
+END(bzero)
+


More information about the svn-src-all mailing list