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