Initial commit
This commit is contained in:
commit
169c65d57e
51358 changed files with 23120455 additions and 0 deletions
7
arch/mn10300/lib/Makefile
Normal file
7
arch/mn10300/lib/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Makefile for the MN10300-specific library files..
|
||||
#
|
||||
|
||||
lib-y = delay.o usercopy.o checksum.o bitops.o memcpy.o memmove.o memset.o
|
||||
lib-y += do_csum.o
|
||||
lib-y += __ashldi3.o __ashrdi3.o __lshrdi3.o negdi2.o __ucmpdi2.o
|
51
arch/mn10300/lib/__ashldi3.S
Normal file
51
arch/mn10300/lib/__ashldi3.S
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* MN10300 64-bit arithmetic left shift
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#include <asm/cache.h>
|
||||
|
||||
.text
|
||||
.balign L1_CACHE_BYTES
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# unsigned long long __ashldi3(unsigned long long value [D1:D0],
|
||||
# unsigned by [(12,SP)])
|
||||
#
|
||||
###############################################################################
|
||||
.globl __ashldi3
|
||||
.type __ashldi3,@function
|
||||
__ashldi3:
|
||||
mov (12,sp),a0
|
||||
and +63,a0
|
||||
beq __ashldi3_zero
|
||||
|
||||
cmp +31,a0
|
||||
bhi __ashldi3_32plus
|
||||
|
||||
# the count is in the range 1-31
|
||||
asl a0,d1
|
||||
|
||||
mov +32,a1
|
||||
sub a0,a1,a1 # a1 = 32 - count
|
||||
lsr a1,d0,a1 # get overflow from LSW -> MSW
|
||||
|
||||
or_asl a1,d1,a0,d0 # insert overflow into MSW and
|
||||
# shift the LSW
|
||||
rets
|
||||
|
||||
.balign L1_CACHE_BYTES
|
||||
# the count is in the range 32-63
|
||||
__ashldi3_32plus:
|
||||
asl a0,d0,d1
|
||||
clr d0
|
||||
__ashldi3_zero:
|
||||
rets
|
||||
|
||||
.size __ashldi3, .-__ashldi3
|
52
arch/mn10300/lib/__ashrdi3.S
Normal file
52
arch/mn10300/lib/__ashrdi3.S
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* MN10300 64-bit arithmetic right shift
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#include <asm/cache.h>
|
||||
|
||||
.text
|
||||
.balign L1_CACHE_BYTES
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# unsigned long long __ashrdi3(unsigned long long value [D1:D0],
|
||||
# unsigned by [(12,SP)])
|
||||
#
|
||||
###############################################################################
|
||||
.globl __ashrdi3
|
||||
.type __ashrdi3,@function
|
||||
__ashrdi3:
|
||||
mov (12,sp),a0
|
||||
and +63,a0
|
||||
beq __ashrdi3_zero
|
||||
|
||||
cmp +31,a0
|
||||
bhi __ashrdi3_32plus
|
||||
|
||||
# the count is in the range 1-31
|
||||
lsr a0,d0
|
||||
|
||||
mov +32,a1
|
||||
sub a0,a1,a1 # a1 = 32 - count
|
||||
asl a1,d1,a1 # get underflow from MSW -> LSW
|
||||
|
||||
or_asr a1,d0,a0,d1 # insert underflow into LSW and
|
||||
# shift the MSW
|
||||
rets
|
||||
|
||||
.balign L1_CACHE_BYTES
|
||||
# the count is in the range 32-63
|
||||
__ashrdi3_32plus:
|
||||
asr a0,d1,d0
|
||||
ext d0 # sign-extend result through MDR
|
||||
mov mdr,d1
|
||||
__ashrdi3_zero:
|
||||
rets
|
||||
|
||||
.size __ashrdi3, .-__ashrdi3
|
52
arch/mn10300/lib/__lshrdi3.S
Normal file
52
arch/mn10300/lib/__lshrdi3.S
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* MN10300 64-bit logical right shift
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <asm/cache.h>
|
||||
|
||||
.text
|
||||
.balign L1_CACHE_BYTES
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# unsigned long long __lshrdi3(unsigned long long value [D1:D0],
|
||||
# unsigned by [(12,SP)])
|
||||
#
|
||||
###############################################################################
|
||||
.globl __lshrdi3
|
||||
.type __lshrdi3,@function
|
||||
__lshrdi3:
|
||||
mov (12,sp),a0
|
||||
and +63,a0
|
||||
beq __lshrdi3_zero
|
||||
|
||||
cmp +31,a0
|
||||
bhi __lshrdi3_32plus
|
||||
|
||||
# the count is in the range 1-31
|
||||
lsr a0,d0
|
||||
|
||||
mov +32,a1
|
||||
sub a0,a1,a1 # a1 = 32 - count
|
||||
asl a1,d1,a1 # get underflow from MSW -> LSW
|
||||
|
||||
or_lsr a1,d0,a0,d1 # insert underflow into LSW and
|
||||
# shift the MSW
|
||||
rets
|
||||
|
||||
.balign L1_CACHE_BYTES
|
||||
# the count is in the range 32-63
|
||||
__lshrdi3_32plus:
|
||||
lsr a0,d1,d0
|
||||
clr d1
|
||||
__lshrdi3_zero:
|
||||
rets
|
||||
|
||||
.size __lshrdi3, .-__lshrdi3
|
43
arch/mn10300/lib/__ucmpdi2.S
Normal file
43
arch/mn10300/lib/__ucmpdi2.S
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* __ucmpdi2.S: 64-bit unsigned compare
|
||||
*
|
||||
* Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
|
||||
.text
|
||||
.p2align 4
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# int __ucmpdi2(unsigned long long a [D0:D1],
|
||||
# unsigned long long b [(SP,12),(SP,16)])
|
||||
#
|
||||
# - returns 0, 1, or 2 as a <, =, > b respectively.
|
||||
#
|
||||
###############################################################################
|
||||
.globl __ucmpdi2
|
||||
.type __ucmpdi2,@function
|
||||
__ucmpdi2:
|
||||
mov (12,sp),a0 # b.lsw
|
||||
mov (16,sp),a1 # b.msw
|
||||
|
||||
sub a0,d0
|
||||
subc a1,d1 # may clear Z, never sets it
|
||||
bne __ucmpdi2_differ # a.msw != b.msw
|
||||
mov +1,d0
|
||||
rets
|
||||
|
||||
__ucmpdi2_differ:
|
||||
# C flag is set if LE, clear if GE
|
||||
subc d0,d0 # -1 if LE, 0 if GE
|
||||
add +1,d0 # 0 if LE, 1 if GE
|
||||
add d0,d0 # 0 if LE, 2 if GE
|
||||
rets
|
||||
|
||||
.size __ucmpdi2, .-__ucmpdi2
|
61
arch/mn10300/lib/ashrdi3.c
Normal file
61
arch/mn10300/lib/ashrdi3.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
|
||||
/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public Licence as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public Licence for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public Licence
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define BITS_PER_UNIT 8
|
||||
|
||||
typedef int SItype __attribute__((mode(SI)));
|
||||
typedef unsigned int USItype __attribute__((mode(SI)));
|
||||
typedef int DItype __attribute__((mode(DI)));
|
||||
typedef int word_type __attribute__((mode(__word__)));
|
||||
|
||||
struct DIstruct {
|
||||
SItype low;
|
||||
SItype high;
|
||||
};
|
||||
|
||||
union DIunion {
|
||||
struct DIstruct s;
|
||||
DItype ll;
|
||||
};
|
||||
|
||||
DItype __ashrdi3(DItype u, word_type b)
|
||||
{
|
||||
union DIunion w;
|
||||
union DIunion uu;
|
||||
word_type bm;
|
||||
|
||||
if (b == 0)
|
||||
return u;
|
||||
|
||||
uu.ll = u;
|
||||
|
||||
bm = (sizeof(SItype) * BITS_PER_UNIT) - b;
|
||||
if (bm <= 0) {
|
||||
/* w.s.high = 1..1 or 0..0 */
|
||||
w.s.high = uu.s.high >> (sizeof(SItype) * BITS_PER_UNIT - 1);
|
||||
w.s.low = uu.s.high >> -bm;
|
||||
} else {
|
||||
USItype carries = (USItype)uu.s.high << bm;
|
||||
w.s.high = uu.s.high >> b;
|
||||
w.s.low = ((USItype)uu.s.low >> b) | carries;
|
||||
}
|
||||
|
||||
return w.ll;
|
||||
}
|
50
arch/mn10300/lib/bitops.c
Normal file
50
arch/mn10300/lib/bitops.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* MN10300 Non-trivial bit operations
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <asm/bitops.h>
|
||||
|
||||
/*
|
||||
* try flipping a bit using BSET and BCLR
|
||||
*/
|
||||
void change_bit(unsigned long nr, volatile void *addr)
|
||||
{
|
||||
if (test_bit(nr, addr))
|
||||
goto try_clear_bit;
|
||||
|
||||
try_set_bit:
|
||||
if (!test_and_set_bit(nr, addr))
|
||||
return;
|
||||
|
||||
try_clear_bit:
|
||||
if (test_and_clear_bit(nr, addr))
|
||||
return;
|
||||
|
||||
goto try_set_bit;
|
||||
}
|
||||
|
||||
/*
|
||||
* try flipping a bit using BSET and BCLR and returning the old value
|
||||
*/
|
||||
int test_and_change_bit(unsigned long nr, volatile void *addr)
|
||||
{
|
||||
if (test_bit(nr, addr))
|
||||
goto try_clear_bit;
|
||||
|
||||
try_set_bit:
|
||||
if (!test_and_set_bit(nr, addr))
|
||||
return 0;
|
||||
|
||||
try_clear_bit:
|
||||
if (test_and_clear_bit(nr, addr))
|
||||
return 1;
|
||||
|
||||
goto try_set_bit;
|
||||
}
|
100
arch/mn10300/lib/checksum.c
Normal file
100
arch/mn10300/lib/checksum.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* MN10300 Optimised checksumming wrappers
|
||||
*
|
||||
* Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/checksum.h>
|
||||
#include "internal.h"
|
||||
|
||||
static inline unsigned short from32to16(__wsum sum)
|
||||
{
|
||||
asm(" add %1,%0 \n"
|
||||
" addc 0xffff,%0 \n"
|
||||
: "=r" (sum)
|
||||
: "r" (sum << 16), "0" (sum & 0xffff0000)
|
||||
: "cc"
|
||||
);
|
||||
return sum >> 16;
|
||||
}
|
||||
|
||||
__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
||||
{
|
||||
return ~do_csum(iph, ihl * 4);
|
||||
}
|
||||
EXPORT_SYMBOL(ip_fast_csum);
|
||||
|
||||
__wsum csum_partial(const void *buff, int len, __wsum sum)
|
||||
{
|
||||
__wsum result;
|
||||
|
||||
result = do_csum(buff, len);
|
||||
result += sum;
|
||||
if (sum > result)
|
||||
result++;
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial);
|
||||
|
||||
__sum16 ip_compute_csum(const void *buff, int len)
|
||||
{
|
||||
return ~from32to16(do_csum(buff, len));
|
||||
}
|
||||
EXPORT_SYMBOL(ip_compute_csum);
|
||||
|
||||
__wsum csum_partial_copy(const void *src, void *dst, int len, __wsum sum)
|
||||
{
|
||||
copy_from_user(dst, src, len);
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial_copy);
|
||||
|
||||
__wsum csum_partial_copy_nocheck(const void *src, void *dst,
|
||||
int len, __wsum sum)
|
||||
{
|
||||
sum = csum_partial(src, len, sum);
|
||||
memcpy(dst, src, len);
|
||||
return sum;
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial_copy_nocheck);
|
||||
|
||||
__wsum csum_partial_copy_from_user(const void *src, void *dst,
|
||||
int len, __wsum sum,
|
||||
int *err_ptr)
|
||||
{
|
||||
int missing;
|
||||
|
||||
missing = copy_from_user(dst, src, len);
|
||||
if (missing) {
|
||||
memset(dst + len - missing, 0, missing);
|
||||
*err_ptr = -EFAULT;
|
||||
}
|
||||
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial_copy_from_user);
|
||||
|
||||
__wsum csum_and_copy_to_user(const void *src, void *dst,
|
||||
int len, __wsum sum,
|
||||
int *err_ptr)
|
||||
{
|
||||
int missing;
|
||||
|
||||
missing = copy_to_user(dst, src, len);
|
||||
if (missing) {
|
||||
memset(dst + len - missing, 0, missing);
|
||||
*err_ptr = -EFAULT;
|
||||
}
|
||||
|
||||
return csum_partial(src, len, sum);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_and_copy_to_user);
|
51
arch/mn10300/lib/delay.c
Normal file
51
arch/mn10300/lib/delay.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* MN10300 Short delay interpolation routines
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
/*
|
||||
* basic delay loop
|
||||
*/
|
||||
void __delay(unsigned long loops)
|
||||
{
|
||||
int d0;
|
||||
|
||||
asm volatile(
|
||||
" bra 1f \n"
|
||||
" .align 4 \n"
|
||||
"1: bra 2f \n"
|
||||
" .align 4 \n"
|
||||
"2: add -1,%0 \n"
|
||||
" bne 2b \n"
|
||||
: "=&d" (d0)
|
||||
: "0" (loops)
|
||||
: "cc");
|
||||
}
|
||||
EXPORT_SYMBOL(__delay);
|
||||
|
||||
/*
|
||||
* handle a delay specified in terms of microseconds
|
||||
*/
|
||||
void __udelay(unsigned long usecs)
|
||||
{
|
||||
unsigned long start, stop, cnt;
|
||||
|
||||
/* usecs * CLK / 1E6 */
|
||||
stop = __muldiv64u(usecs, MN10300_TSCCLK, 1000000);
|
||||
start = TMTSCBC;
|
||||
|
||||
do {
|
||||
cnt = start - TMTSCBC;
|
||||
} while (cnt < stop);
|
||||
}
|
||||
EXPORT_SYMBOL(__udelay);
|
157
arch/mn10300/lib/do_csum.S
Normal file
157
arch/mn10300/lib/do_csum.S
Normal file
|
@ -0,0 +1,157 @@
|
|||
/* Optimised simple memory checksum
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#include <asm/cache.h>
|
||||
|
||||
.section .text
|
||||
.balign L1_CACHE_BYTES
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# unsigned int do_csum(const unsigned char *buff, int len)
|
||||
#
|
||||
###############################################################################
|
||||
.globl do_csum
|
||||
.type do_csum,@function
|
||||
do_csum:
|
||||
movm [d2,d3],(sp)
|
||||
mov d1,d2 # count
|
||||
mov d0,a0 # buff
|
||||
mov a0,a1
|
||||
clr d1 # accumulator
|
||||
|
||||
cmp +0,d2
|
||||
ble do_csum_done # check for zero length or negative
|
||||
|
||||
# 4-byte align the buffer pointer
|
||||
btst +3,a0
|
||||
beq do_csum_now_4b_aligned
|
||||
|
||||
btst +1,a0
|
||||
beq do_csum_addr_not_odd
|
||||
movbu (a0),d0
|
||||
inc a0
|
||||
asl +8,d0
|
||||
add d0,d1
|
||||
add -1,d2
|
||||
|
||||
do_csum_addr_not_odd:
|
||||
cmp +2,d2
|
||||
bcs do_csum_fewer_than_4
|
||||
btst +2,a0
|
||||
beq do_csum_now_4b_aligned
|
||||
movhu (a0+),d0
|
||||
add d0,d1
|
||||
add -2,d2
|
||||
cmp +4,d2
|
||||
bcs do_csum_fewer_than_4
|
||||
|
||||
do_csum_now_4b_aligned:
|
||||
# we want to checksum as much as we can in chunks of 32 bytes
|
||||
cmp +31,d2
|
||||
bls do_csum_remainder # 4-byte aligned remainder
|
||||
|
||||
add -32,d2
|
||||
mov +32,d3
|
||||
|
||||
do_csum_loop:
|
||||
mov (a0+),d0
|
||||
mov (a0+),e0
|
||||
mov (a0+),e1
|
||||
mov (a0+),e3
|
||||
add d0,d1
|
||||
addc e0,d1
|
||||
addc e1,d1
|
||||
addc e3,d1
|
||||
mov (a0+),d0
|
||||
mov (a0+),e0
|
||||
mov (a0+),e1
|
||||
mov (a0+),e3
|
||||
addc d0,d1
|
||||
addc e0,d1
|
||||
addc e1,d1
|
||||
addc e3,d1
|
||||
addc +0,d1
|
||||
|
||||
sub d3,d2
|
||||
bcc do_csum_loop
|
||||
|
||||
add d3,d2
|
||||
beq do_csum_done
|
||||
|
||||
do_csum_remainder:
|
||||
# cut 16-31 bytes down to 0-15
|
||||
cmp +16,d2
|
||||
bcs do_csum_fewer_than_16
|
||||
mov (a0+),d0
|
||||
mov (a0+),e0
|
||||
mov (a0+),e1
|
||||
mov (a0+),e3
|
||||
add d0,d1
|
||||
addc e0,d1
|
||||
addc e1,d1
|
||||
addc e3,d1
|
||||
addc +0,d1
|
||||
add -16,d2
|
||||
beq do_csum_done
|
||||
|
||||
do_csum_fewer_than_16:
|
||||
# copy the remaining whole words
|
||||
cmp +4,d2
|
||||
bcs do_csum_fewer_than_4
|
||||
cmp +8,d2
|
||||
bcs do_csum_one_word
|
||||
cmp +12,d2
|
||||
bcs do_csum_two_words
|
||||
mov (a0+),d0
|
||||
add d0,d1
|
||||
addc +0,d1
|
||||
do_csum_two_words:
|
||||
mov (a0+),d0
|
||||
add d0,d1
|
||||
addc +0,d1
|
||||
do_csum_one_word:
|
||||
mov (a0+),d0
|
||||
add d0,d1
|
||||
addc +0,d1
|
||||
|
||||
do_csum_fewer_than_4:
|
||||
and +3,d2
|
||||
beq do_csum_done
|
||||
xor_cmp d0,d0,+2,d2
|
||||
bcs do_csum_fewer_than_2
|
||||
movhu (a0+),d0
|
||||
and +1,d2
|
||||
beq do_csum_add_last_bit
|
||||
do_csum_fewer_than_2:
|
||||
movbu (a0),d3
|
||||
add d3,d0
|
||||
do_csum_add_last_bit:
|
||||
add d0,d1
|
||||
addc +0,d1
|
||||
|
||||
do_csum_done:
|
||||
# compress the checksum down to 16 bits
|
||||
mov +0xffff0000,d0
|
||||
and d1,d0
|
||||
asl +16,d1
|
||||
add d1,d0
|
||||
addc +0xffff,d0
|
||||
lsr +16,d0
|
||||
|
||||
# flip the halves of the word result if the buffer was oddly aligned
|
||||
and +1,a1
|
||||
beq do_csum_not_oddly_aligned
|
||||
swaph d0,d0 # exchange bits 15:8 with 7:0
|
||||
|
||||
do_csum_not_oddly_aligned:
|
||||
ret [d2,d3],8
|
||||
|
||||
.size do_csum, .-do_csum
|
15
arch/mn10300/lib/internal.h
Normal file
15
arch/mn10300/lib/internal.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* Internal definitions for the arch part of the kernel library
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* do_csum.S
|
||||
*/
|
||||
extern unsigned int do_csum(const unsigned char *, size_t);
|
60
arch/mn10300/lib/lshrdi3.c
Normal file
60
arch/mn10300/lib/lshrdi3.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
|
||||
/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public Licence as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public Licence for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public Licence
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define BITS_PER_UNIT 8
|
||||
|
||||
typedef int SItype __attribute__((mode(SI)));
|
||||
typedef unsigned int USItype __attribute__((mode(SI)));
|
||||
typedef int DItype __attribute__((mode(DI)));
|
||||
typedef int word_type __attribute__((mode(__word__)));
|
||||
|
||||
struct DIstruct {
|
||||
SItype low;
|
||||
SItype high;
|
||||
};
|
||||
|
||||
union DIunion {
|
||||
struct DIstruct s;
|
||||
DItype ll;
|
||||
};
|
||||
|
||||
DItype __lshrdi3(DItype u, word_type b)
|
||||
{
|
||||
union DIunion w;
|
||||
word_type bm;
|
||||
union DIunion uu;
|
||||
|
||||
if (b == 0)
|
||||
return u;
|
||||
|
||||
uu.ll = u;
|
||||
|
||||
bm = (sizeof(SItype) * BITS_PER_UNIT) - b;
|
||||
if (bm <= 0) {
|
||||
w.s.high = 0;
|
||||
w.s.low = (USItype) uu.s.high >> -bm;
|
||||
} else {
|
||||
USItype carries = (USItype) uu.s.high << bm;
|
||||
w.s.high = (USItype) uu.s.high >> b;
|
||||
w.s.low = ((USItype) uu.s.low >> b) | carries;
|
||||
}
|
||||
|
||||
return w.ll;
|
||||
}
|
135
arch/mn10300/lib/memcpy.S
Normal file
135
arch/mn10300/lib/memcpy.S
Normal file
|
@ -0,0 +1,135 @@
|
|||
/* MN10300 Optimised simple memory to memory copy
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#include <asm/cache.h>
|
||||
|
||||
.section .text
|
||||
.balign L1_CACHE_BYTES
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# void *memcpy(void *dst, const void *src, size_t n)
|
||||
#
|
||||
###############################################################################
|
||||
.globl memcpy
|
||||
.type memcpy,@function
|
||||
memcpy:
|
||||
movm [d2,d3],(sp)
|
||||
mov d0,(12,sp)
|
||||
mov d1,(16,sp)
|
||||
mov (20,sp),d2 # count
|
||||
mov d0,a0 # dst
|
||||
mov d1,a1 # src
|
||||
mov d0,e3 # the return value
|
||||
|
||||
cmp +0,d2
|
||||
beq memcpy_done # return if zero-length copy
|
||||
|
||||
# see if the three parameters are all four-byte aligned
|
||||
or d0,d1,d3
|
||||
or d2,d3
|
||||
and +3,d3
|
||||
bne memcpy_1 # jump if not
|
||||
|
||||
# we want to transfer as much as we can in chunks of 32 bytes
|
||||
cmp +31,d2
|
||||
bls memcpy_4_remainder # 4-byte aligned remainder
|
||||
|
||||
movm [exreg1],(sp)
|
||||
add -32,d2
|
||||
mov +32,d3
|
||||
|
||||
memcpy_4_loop:
|
||||
mov (a1+),d0
|
||||
mov (a1+),d1
|
||||
mov (a1+),e0
|
||||
mov (a1+),e1
|
||||
mov (a1+),e4
|
||||
mov (a1+),e5
|
||||
mov (a1+),e6
|
||||
mov (a1+),e7
|
||||
mov d0,(a0+)
|
||||
mov d1,(a0+)
|
||||
mov e0,(a0+)
|
||||
mov e1,(a0+)
|
||||
mov e4,(a0+)
|
||||
mov e5,(a0+)
|
||||
mov e6,(a0+)
|
||||
mov e7,(a0+)
|
||||
|
||||
sub d3,d2
|
||||
bcc memcpy_4_loop
|
||||
|
||||
movm (sp),[exreg1]
|
||||
add d3,d2
|
||||
beq memcpy_4_no_remainder
|
||||
|
||||
memcpy_4_remainder:
|
||||
# cut 4-7 words down to 0-3
|
||||
cmp +16,d2
|
||||
bcs memcpy_4_three_or_fewer_words
|
||||
mov (a1+),d0
|
||||
mov (a1+),d1
|
||||
mov (a1+),e0
|
||||
mov (a1+),e1
|
||||
mov d0,(a0+)
|
||||
mov d1,(a0+)
|
||||
mov e0,(a0+)
|
||||
mov e1,(a0+)
|
||||
add -16,d2
|
||||
beq memcpy_4_no_remainder
|
||||
|
||||
# copy the remaining 1, 2 or 3 words
|
||||
memcpy_4_three_or_fewer_words:
|
||||
cmp +8,d2
|
||||
bcs memcpy_4_one_word
|
||||
beq memcpy_4_two_words
|
||||
mov (a1+),d0
|
||||
mov d0,(a0+)
|
||||
memcpy_4_two_words:
|
||||
mov (a1+),d0
|
||||
mov d0,(a0+)
|
||||
memcpy_4_one_word:
|
||||
mov (a1+),d0
|
||||
mov d0,(a0+)
|
||||
|
||||
memcpy_4_no_remainder:
|
||||
# check we copied the correct amount
|
||||
# TODO: REMOVE CHECK
|
||||
sub e3,a0,d2
|
||||
mov (20,sp),d1
|
||||
cmp d2,d1
|
||||
beq memcpy_done
|
||||
break
|
||||
break
|
||||
break
|
||||
|
||||
memcpy_done:
|
||||
mov e3,a0
|
||||
ret [d2,d3],8
|
||||
|
||||
# handle misaligned copying
|
||||
memcpy_1:
|
||||
add -1,d2
|
||||
mov +1,d3
|
||||
setlb # setlb requires the next insns
|
||||
# to occupy exactly 4 bytes
|
||||
|
||||
sub d3,d2
|
||||
movbu (a1),d0
|
||||
movbu d0,(a0)
|
||||
add_add d3,a1,d3,a0
|
||||
lcc
|
||||
|
||||
mov e3,a0
|
||||
ret [d2,d3],8
|
||||
|
||||
memcpy_end:
|
||||
.size memcpy, memcpy_end-memcpy
|
160
arch/mn10300/lib/memmove.S
Normal file
160
arch/mn10300/lib/memmove.S
Normal file
|
@ -0,0 +1,160 @@
|
|||
/* MN10300 Optimised simple memory to memory copy, with support for overlapping
|
||||
* regions
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#include <asm/cache.h>
|
||||
|
||||
.section .text
|
||||
.balign L1_CACHE_BYTES
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# void *memmove(void *dst, const void *src, size_t n)
|
||||
#
|
||||
###############################################################################
|
||||
.globl memmove
|
||||
.type memmove,@function
|
||||
memmove:
|
||||
# fall back to memcpy if dst < src to work bottom up
|
||||
cmp d1,d0
|
||||
bcs memmove_memcpy
|
||||
|
||||
# work top down
|
||||
movm [d2,d3],(sp)
|
||||
mov d0,(12,sp)
|
||||
mov d1,(16,sp)
|
||||
mov (20,sp),d2 # count
|
||||
add d0,d2,a0 # dst end
|
||||
add d1,d2,a1 # src end
|
||||
mov d0,e3 # the return value
|
||||
|
||||
cmp +0,d2
|
||||
beq memmove_done # return if zero-length copy
|
||||
|
||||
# see if the three parameters are all four-byte aligned
|
||||
or d0,d1,d3
|
||||
or d2,d3
|
||||
and +3,d3
|
||||
bne memmove_1 # jump if not
|
||||
|
||||
# we want to transfer as much as we can in chunks of 32 bytes
|
||||
add -4,a1
|
||||
cmp +31,d2
|
||||
bls memmove_4_remainder # 4-byte aligned remainder
|
||||
|
||||
add -32,d2
|
||||
mov +32,d3
|
||||
|
||||
memmove_4_loop:
|
||||
mov (a1),d0
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d0,(a0)
|
||||
mov (a1),d1
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d1,(a0)
|
||||
|
||||
mov (a1),d0
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d0,(a0)
|
||||
mov (a1),d1
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d1,(a0)
|
||||
|
||||
mov (a1),d0
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d0,(a0)
|
||||
mov (a1),d1
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d1,(a0)
|
||||
|
||||
mov (a1),d0
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d0,(a0)
|
||||
mov (a1),d1
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d1,(a0)
|
||||
|
||||
sub d3,d2
|
||||
bcc memmove_4_loop
|
||||
|
||||
add d3,d2
|
||||
beq memmove_4_no_remainder
|
||||
|
||||
memmove_4_remainder:
|
||||
# cut 4-7 words down to 0-3
|
||||
cmp +16,d2
|
||||
bcs memmove_4_three_or_fewer_words
|
||||
mov (a1),d0
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d0,(a0)
|
||||
mov (a1),d1
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d1,(a0)
|
||||
mov (a1),e0
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov e0,(a0)
|
||||
mov (a1),e1
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov e1,(a0)
|
||||
add -16,d2
|
||||
beq memmove_4_no_remainder
|
||||
|
||||
# copy the remaining 1, 2 or 3 words
|
||||
memmove_4_three_or_fewer_words:
|
||||
cmp +8,d2
|
||||
bcs memmove_4_one_word
|
||||
beq memmove_4_two_words
|
||||
mov (a1),d0
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d0,(a0)
|
||||
memmove_4_two_words:
|
||||
mov (a1),d0
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d0,(a0)
|
||||
memmove_4_one_word:
|
||||
mov (a1),d0
|
||||
sub_sub +4,a1,+4,a0
|
||||
mov d0,(a0)
|
||||
|
||||
memmove_4_no_remainder:
|
||||
# check we copied the correct amount
|
||||
# TODO: REMOVE CHECK
|
||||
sub e3,a0,d2
|
||||
beq memmove_done
|
||||
break
|
||||
break
|
||||
break
|
||||
|
||||
memmove_done:
|
||||
mov e3,a0
|
||||
ret [d2,d3],8
|
||||
|
||||
# handle misaligned copying
|
||||
memmove_1:
|
||||
add -1,a1
|
||||
add -1,d2
|
||||
mov +1,d3
|
||||
setlb # setlb requires the next insns
|
||||
# to occupy exactly 4 bytes
|
||||
|
||||
sub d3,d2
|
||||
movbu (a1),d0
|
||||
sub_sub d3,a1,d3,a0
|
||||
movbu d0,(a0)
|
||||
lcc
|
||||
|
||||
mov e3,a0
|
||||
ret [d2,d3],8
|
||||
|
||||
memmove_memcpy:
|
||||
jmp memcpy
|
||||
|
||||
memmove_end:
|
||||
.size memmove, memmove_end-memmove
|
121
arch/mn10300/lib/memset.S
Normal file
121
arch/mn10300/lib/memset.S
Normal file
|
@ -0,0 +1,121 @@
|
|||
/* Optimised simple memory fill
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#include <asm/cache.h>
|
||||
|
||||
.section .text
|
||||
.balign L1_CACHE_BYTES
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# void *memset(void *dst, int c, size_t n)
|
||||
#
|
||||
###############################################################################
|
||||
.globl memset
|
||||
.type memset,@function
|
||||
memset:
|
||||
movm [d2,d3],(sp)
|
||||
mov d0,(12,sp)
|
||||
mov d1,(16,sp)
|
||||
mov (20,sp),d2 # count
|
||||
mov d0,a0 # dst
|
||||
mov d0,e3 # the return value
|
||||
|
||||
cmp +0,d2
|
||||
beq memset_done # return if zero-length fill
|
||||
|
||||
# see if the region parameters are four-byte aligned
|
||||
or d0,d2,d3
|
||||
and +3,d3
|
||||
bne memset_1 # jump if not
|
||||
|
||||
extbu d1
|
||||
mov_asl d1,d3,8,d1
|
||||
or_asl d1,d3,8,d1
|
||||
or_asl d1,d3,8,d1
|
||||
or d3,d1
|
||||
|
||||
# we want to transfer as much as we can in chunks of 32 bytes
|
||||
cmp +31,d2
|
||||
bls memset_4_remainder # 4-byte aligned remainder
|
||||
|
||||
add -32,d2
|
||||
mov +32,d3
|
||||
|
||||
memset_4_loop:
|
||||
mov d1,(a0+)
|
||||
mov d1,(a0+)
|
||||
mov d1,(a0+)
|
||||
mov d1,(a0+)
|
||||
mov d1,(a0+)
|
||||
mov d1,(a0+)
|
||||
mov d1,(a0+)
|
||||
mov d1,(a0+)
|
||||
|
||||
sub d3,d2
|
||||
bcc memset_4_loop
|
||||
|
||||
add d3,d2
|
||||
beq memset_4_no_remainder
|
||||
|
||||
memset_4_remainder:
|
||||
# cut 4-7 words down to 0-3
|
||||
cmp +16,d2
|
||||
bcs memset_4_three_or_fewer_words
|
||||
mov d1,(a0+)
|
||||
mov d1,(a0+)
|
||||
mov d1,(a0+)
|
||||
mov d1,(a0+)
|
||||
add -16,d2
|
||||
beq memset_4_no_remainder
|
||||
|
||||
# copy the remaining 1, 2 or 3 words
|
||||
memset_4_three_or_fewer_words:
|
||||
cmp +8,d2
|
||||
bcs memset_4_one_word
|
||||
beq memset_4_two_words
|
||||
mov d1,(a0+)
|
||||
memset_4_two_words:
|
||||
mov d1,(a0+)
|
||||
memset_4_one_word:
|
||||
mov d1,(a0+)
|
||||
|
||||
memset_4_no_remainder:
|
||||
# check we set the correct amount
|
||||
# TODO: REMOVE CHECK
|
||||
sub e3,a0,d2
|
||||
mov (20,sp),d1
|
||||
cmp d2,d1
|
||||
beq memset_done
|
||||
break
|
||||
break
|
||||
break
|
||||
|
||||
memset_done:
|
||||
mov e3,a0
|
||||
ret [d2,d3],8
|
||||
|
||||
# handle misaligned copying
|
||||
memset_1:
|
||||
add -1,d2
|
||||
mov +1,d3
|
||||
setlb # setlb requires the next insns
|
||||
# to occupy exactly 4 bytes
|
||||
|
||||
sub d3,d2
|
||||
movbu d1,(a0)
|
||||
inc a0
|
||||
lcc
|
||||
|
||||
mov e3,a0
|
||||
ret [d2,d3],8
|
||||
|
||||
memset_end:
|
||||
.size memset, memset_end-memset
|
57
arch/mn10300/lib/negdi2.c
Normal file
57
arch/mn10300/lib/negdi2.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* More subroutines needed by GCC output code on some machines. */
|
||||
/* Compile this one with gcc. */
|
||||
/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public Licence as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
In addition to the permissions in the GNU General Public Licence, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file into combinations with other programs,
|
||||
and to distribute those combinations without any restriction coming
|
||||
from the use of this file. (The General Public Licence restrictions
|
||||
do apply in other respects; for example, they cover modification of
|
||||
the file, and distribution when not linked into a combine
|
||||
executable.)
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public Licence for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public Licence
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* It is incorrect to include config.h here, because this file is being
|
||||
compiled for the target, and hence definitions concerning only the host
|
||||
do not apply. */
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
union DWunion {
|
||||
s64 ll;
|
||||
struct {
|
||||
s32 low;
|
||||
s32 high;
|
||||
} s;
|
||||
};
|
||||
|
||||
s64 __negdi2(s64 u)
|
||||
{
|
||||
union DWunion w;
|
||||
union DWunion uu;
|
||||
|
||||
uu.ll = u;
|
||||
|
||||
w.s.low = -uu.s.low;
|
||||
w.s.high = -uu.s.high - ((u32) w.s.low > 0);
|
||||
|
||||
return w.ll;
|
||||
}
|
166
arch/mn10300/lib/usercopy.c
Normal file
166
arch/mn10300/lib/usercopy.c
Normal file
|
@ -0,0 +1,166 @@
|
|||
/* MN10300 Userspace accessor functions
|
||||
*
|
||||
* Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
unsigned long
|
||||
__generic_copy_to_user(void *to, const void *from, unsigned long n)
|
||||
{
|
||||
if (access_ok(VERIFY_WRITE, to, n))
|
||||
__copy_user(to, from, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
__generic_copy_from_user(void *to, const void *from, unsigned long n)
|
||||
{
|
||||
if (access_ok(VERIFY_READ, from, n))
|
||||
__copy_user_zeroing(to, from, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a null terminated string from userspace.
|
||||
*/
|
||||
#define __do_strncpy_from_user(dst, src, count, res) \
|
||||
do { \
|
||||
int w; \
|
||||
asm volatile( \
|
||||
" mov %1,%0\n" \
|
||||
" cmp 0,%1\n" \
|
||||
" beq 2f\n" \
|
||||
"0:\n" \
|
||||
" movbu (%5),%2\n" \
|
||||
"1:\n" \
|
||||
" movbu %2,(%6)\n" \
|
||||
" inc %5\n" \
|
||||
" inc %6\n" \
|
||||
" cmp 0,%2\n" \
|
||||
" beq 2f\n" \
|
||||
" add -1,%1\n" \
|
||||
" bne 0b\n" \
|
||||
"2:\n" \
|
||||
" sub %1,%0\n" \
|
||||
"3:\n" \
|
||||
" .section .fixup,\"ax\"\n" \
|
||||
"4:\n" \
|
||||
" mov %3,%0\n" \
|
||||
" jmp 3b\n" \
|
||||
" .previous\n" \
|
||||
" .section __ex_table,\"a\"\n" \
|
||||
" .balign 4\n" \
|
||||
" .long 0b,4b\n" \
|
||||
" .long 1b,4b\n" \
|
||||
" .previous" \
|
||||
:"=&r"(res), "=r"(count), "=&r"(w) \
|
||||
:"i"(-EFAULT), "1"(count), "a"(src), "a"(dst) \
|
||||
: "memory", "cc"); \
|
||||
} while (0)
|
||||
|
||||
long
|
||||
__strncpy_from_user(char *dst, const char *src, long count)
|
||||
{
|
||||
long res;
|
||||
__do_strncpy_from_user(dst, src, count, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
long
|
||||
strncpy_from_user(char *dst, const char *src, long count)
|
||||
{
|
||||
long res = -EFAULT;
|
||||
if (access_ok(VERIFY_READ, src, 1))
|
||||
__do_strncpy_from_user(dst, src, count, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clear a userspace memory
|
||||
*/
|
||||
#define __do_clear_user(addr, size) \
|
||||
do { \
|
||||
int w; \
|
||||
asm volatile( \
|
||||
" cmp 0,%0\n" \
|
||||
" beq 1f\n" \
|
||||
" clr %1\n" \
|
||||
"0: movbu %1,(%3,%2)\n" \
|
||||
" inc %3\n" \
|
||||
" cmp %0,%3\n" \
|
||||
" bne 0b\n" \
|
||||
"1:\n" \
|
||||
" sub %3,%0\n" \
|
||||
"2:\n" \
|
||||
".section .fixup,\"ax\"\n" \
|
||||
"3: jmp 2b\n" \
|
||||
".previous\n" \
|
||||
".section __ex_table,\"a\"\n" \
|
||||
" .balign 4\n" \
|
||||
" .long 0b,3b\n" \
|
||||
".previous\n" \
|
||||
: "+r"(size), "=&r"(w) \
|
||||
: "a"(addr), "d"(0) \
|
||||
: "memory", "cc"); \
|
||||
} while (0)
|
||||
|
||||
unsigned long
|
||||
__clear_user(void *to, unsigned long n)
|
||||
{
|
||||
__do_clear_user(to, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
clear_user(void *to, unsigned long n)
|
||||
{
|
||||
if (access_ok(VERIFY_WRITE, to, n))
|
||||
__do_clear_user(to, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the size of a string (including the ending 0)
|
||||
*
|
||||
* Return 0 on exception, a value greater than N if too long
|
||||
*/
|
||||
long strnlen_user(const char *s, long n)
|
||||
{
|
||||
unsigned long res, w;
|
||||
|
||||
if (!__addr_ok(s))
|
||||
return 0;
|
||||
|
||||
if (n < 0 || n + (u_long) s > current_thread_info()->addr_limit.seg)
|
||||
n = current_thread_info()->addr_limit.seg - (u_long)s;
|
||||
|
||||
asm volatile(
|
||||
"0: cmp %4,%0\n"
|
||||
" beq 2f\n"
|
||||
"1: movbu (%0,%3),%1\n"
|
||||
" inc %0\n"
|
||||
" cmp 0,%1\n"
|
||||
" beq 3f\n"
|
||||
" bra 0b\n"
|
||||
"2: clr %0\n"
|
||||
"3:\n"
|
||||
".section .fixup,\"ax\"\n"
|
||||
"4: jmp 2b\n"
|
||||
".previous\n"
|
||||
".section __ex_table,\"a\"\n"
|
||||
" .balign 4\n"
|
||||
" .long 1b,4b\n"
|
||||
".previous\n"
|
||||
:"=d"(res), "=&r"(w)
|
||||
:"0"(0), "a"(s), "r"(n)
|
||||
: "memory", "cc");
|
||||
return res;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue