162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
362306a36Sopenharmony_ci * Copyright (C) 2008-2009 PetaLogix
462306a36Sopenharmony_ci * Copyright (C) 2007 John Williams
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Reasonably optimised generic C-code for memset on Microblaze
762306a36Sopenharmony_ci * This is generic C code to do efficient, alignment-aware memcpy.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
1062306a36Sopenharmony_ci * http://www.embedded.com/showArticle.jhtml?articleID=19205567
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * Attempts were made, unsuccessfully, to contact the original
1362306a36Sopenharmony_ci * author of this code (Michael Morrow, Intel).  Below is the original
1462306a36Sopenharmony_ci * copyright notice.
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci * This software has been developed by Intel Corporation.
1762306a36Sopenharmony_ci * Intel specifically disclaims all warranties, express or
1862306a36Sopenharmony_ci * implied, and all liability, including consequential and
1962306a36Sopenharmony_ci * other indirect damages, for the use of this program, including
2062306a36Sopenharmony_ci * liability for infringement of any proprietary rights,
2162306a36Sopenharmony_ci * and including the warranties of merchantability and fitness
2262306a36Sopenharmony_ci * for a particular purpose. Intel does not assume any
2362306a36Sopenharmony_ci * responsibility for and errors which may appear in this program
2462306a36Sopenharmony_ci * not any responsibility to update it.
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#include <linux/export.h>
2862306a36Sopenharmony_ci#include <linux/types.h>
2962306a36Sopenharmony_ci#include <linux/stddef.h>
3062306a36Sopenharmony_ci#include <linux/compiler.h>
3162306a36Sopenharmony_ci#include <linux/string.h>
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#ifdef CONFIG_OPT_LIB_FUNCTION
3462306a36Sopenharmony_civoid *memset(void *v_src, int c, __kernel_size_t n)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	char *src = v_src;
3762306a36Sopenharmony_ci	uint32_t *i_src;
3862306a36Sopenharmony_ci	uint32_t w32 = 0;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	/* Truncate c to 8 bits */
4162306a36Sopenharmony_ci	c = (c & 0xFF);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	if (unlikely(c)) {
4462306a36Sopenharmony_ci		/* Make a repeating word out of it */
4562306a36Sopenharmony_ci		w32 = c;
4662306a36Sopenharmony_ci		w32 |= w32 << 8;
4762306a36Sopenharmony_ci		w32 |= w32 << 16;
4862306a36Sopenharmony_ci	}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	if (likely(n >= 4)) {
5162306a36Sopenharmony_ci		/* Align the destination to a word boundary */
5262306a36Sopenharmony_ci		/* This is done in an endian independent manner */
5362306a36Sopenharmony_ci		switch ((unsigned) src & 3) {
5462306a36Sopenharmony_ci		case 1:
5562306a36Sopenharmony_ci			*src++ = c;
5662306a36Sopenharmony_ci			--n;
5762306a36Sopenharmony_ci			fallthrough;
5862306a36Sopenharmony_ci		case 2:
5962306a36Sopenharmony_ci			*src++ = c;
6062306a36Sopenharmony_ci			--n;
6162306a36Sopenharmony_ci			fallthrough;
6262306a36Sopenharmony_ci		case 3:
6362306a36Sopenharmony_ci			*src++ = c;
6462306a36Sopenharmony_ci			--n;
6562306a36Sopenharmony_ci		}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci		i_src  = (void *)src;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci		/* Do as many full-word copies as we can */
7062306a36Sopenharmony_ci		for (; n >= 4; n -= 4)
7162306a36Sopenharmony_ci			*i_src++ = w32;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci		src  = (void *)i_src;
7462306a36Sopenharmony_ci	}
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	/* Simple, byte oriented memset or the rest of count. */
7762306a36Sopenharmony_ci	switch (n) {
7862306a36Sopenharmony_ci	case 3:
7962306a36Sopenharmony_ci		*src++ = c;
8062306a36Sopenharmony_ci		fallthrough;
8162306a36Sopenharmony_ci	case 2:
8262306a36Sopenharmony_ci		*src++ = c;
8362306a36Sopenharmony_ci		fallthrough;
8462306a36Sopenharmony_ci	case 1:
8562306a36Sopenharmony_ci		*src++ = c;
8662306a36Sopenharmony_ci		break;
8762306a36Sopenharmony_ci	default:
8862306a36Sopenharmony_ci		break;
8962306a36Sopenharmony_ci	}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	return v_src;
9262306a36Sopenharmony_ci}
9362306a36Sopenharmony_ciEXPORT_SYMBOL(memset);
9462306a36Sopenharmony_ci#endif /* CONFIG_OPT_LIB_FUNCTION */
95