add cortex-v7a support
How To Run: see TencentOS-tiny\board\ALPHA_I.MX_emmc_256ddr\README.md TODO Next: 1. VFP support 2. fault diagnosis support 3. qemu vexpress ca9 support 4. raspberry pi support 5. SMP support
This commit is contained in:
33
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/ctype.c
Normal file
33
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/ctype.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* linux/lib/ctype.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
#include "ctype.h"
|
||||
|
||||
unsigned char _ctype[] = {
|
||||
_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
|
||||
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
|
||||
_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
|
||||
_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
|
||||
_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
|
||||
_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
|
||||
_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
|
||||
_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
|
||||
_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
|
||||
_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
|
||||
_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
|
||||
_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
|
||||
_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
|
||||
_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
|
||||
_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
|
||||
_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
|
52
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/div64.c
Normal file
52
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/div64.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
|
||||
*
|
||||
* Based on former do_div() implementation from asm-parisc/div64.h:
|
||||
* Copyright (C) 1999 Hewlett-Packard Co
|
||||
* Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
*
|
||||
*
|
||||
* Generic C version of 64bit/32bit division and modulo, with
|
||||
* 64bit result and 32bit remainder.
|
||||
*
|
||||
* The fast case for (n>>32 == 0) is handled inline by do_div().
|
||||
*
|
||||
* Code generated for this function might be very inefficient
|
||||
* for some CPUs. __div64_32() can be overridden by linking arch-specific
|
||||
* assembly versions such as arch/powerpc/lib/div64.S and arch/sh/lib/div64.S.
|
||||
*/
|
||||
|
||||
#include "div64.h"
|
||||
|
||||
unsigned int __div64_32(unsigned long long *n, unsigned int base)
|
||||
{
|
||||
unsigned long long rem = *n;
|
||||
unsigned long long b = base;
|
||||
unsigned long long res, d = 1;
|
||||
unsigned int high = rem >> 32;
|
||||
|
||||
/* Reduce the thing a bit first */
|
||||
res = 0;
|
||||
if (high >= base) {
|
||||
high /= base;
|
||||
res = (unsigned long long ) high << 32;
|
||||
rem -= (unsigned long long ) (high*base) << 32;
|
||||
}
|
||||
|
||||
while ((signed long long )b > 0 && b < rem) {
|
||||
b = b+b;
|
||||
d = d+d;
|
||||
}
|
||||
|
||||
do {
|
||||
if (rem >= b) {
|
||||
rem -= b;
|
||||
res += d;
|
||||
}
|
||||
b >>= 1;
|
||||
d >>= 1;
|
||||
} while (d);
|
||||
|
||||
*n = res;
|
||||
return rem;
|
||||
}
|
323
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/lib1funcs.S
Normal file
323
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/lib1funcs.S
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
|
||||
*
|
||||
* Author: Nicolas Pitre <nico@cam.org>
|
||||
* - contributed to gcc-3.4 on Sep 30, 2003
|
||||
* - adapted for the Linux kernel on Oct 2, 2003
|
||||
*/
|
||||
|
||||
/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file 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, or (at your option) any
|
||||
later version.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, 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 License restrictions
|
||||
do apply in other respects; for example, they cover modification of
|
||||
the file, and distribution when not linked into a combine
|
||||
executable.)
|
||||
|
||||
This file 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 License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/*
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
*/
|
||||
|
||||
#define ALIGN .align 4,0x90
|
||||
#define __LINUX_ARM_ARCH__ 1
|
||||
|
||||
#define ENTRY(name) \
|
||||
.globl name; \
|
||||
ALIGN; \
|
||||
name:
|
||||
|
||||
.macro ARM_DIV_BODY dividend, divisor, result, curbit
|
||||
|
||||
#if __LINUX_ARM_ARCH__ >= 5
|
||||
|
||||
clz \curbit, \divisor
|
||||
clz \result, \dividend
|
||||
sub \result, \curbit, \result
|
||||
mov \curbit, #1
|
||||
mov \divisor, \divisor, lsl \result
|
||||
mov \curbit, \curbit, lsl \result
|
||||
mov \result, #0
|
||||
|
||||
#else
|
||||
|
||||
@ Initially shift the divisor left 3 bits if possible,
|
||||
@ set curbit accordingly. This allows for curbit to be located
|
||||
@ at the left end of each 4 bit nibbles in the division loop
|
||||
@ to save one loop in most cases.
|
||||
tst \divisor, #0xe0000000
|
||||
moveq \divisor, \divisor, lsl #3
|
||||
moveq \curbit, #8
|
||||
movne \curbit, #1
|
||||
|
||||
@ Unless the divisor is very big, shift it up in multiples of
|
||||
@ four bits, since this is the amount of unwinding in the main
|
||||
@ division loop. Continue shifting until the divisor is
|
||||
@ larger than the dividend.
|
||||
1: cmp \divisor, #0x10000000
|
||||
cmplo \divisor, \dividend
|
||||
movlo \divisor, \divisor, lsl #4
|
||||
movlo \curbit, \curbit, lsl #4
|
||||
blo 1b
|
||||
|
||||
@ For very big divisors, we must shift it a bit at a time, or
|
||||
@ we will be in danger of overflowing.
|
||||
1: cmp \divisor, #0x80000000
|
||||
cmplo \divisor, \dividend
|
||||
movlo \divisor, \divisor, lsl #1
|
||||
movlo \curbit, \curbit, lsl #1
|
||||
blo 1b
|
||||
|
||||
mov \result, #0
|
||||
|
||||
#endif
|
||||
|
||||
@ Division loop
|
||||
1: cmp \dividend, \divisor
|
||||
subhs \dividend, \dividend, \divisor
|
||||
orrhs \result, \result, \curbit
|
||||
cmp \dividend, \divisor, lsr #1
|
||||
subhs \dividend, \dividend, \divisor, lsr #1
|
||||
orrhs \result, \result, \curbit, lsr #1
|
||||
cmp \dividend, \divisor, lsr #2
|
||||
subhs \dividend, \dividend, \divisor, lsr #2
|
||||
orrhs \result, \result, \curbit, lsr #2
|
||||
cmp \dividend, \divisor, lsr #3
|
||||
subhs \dividend, \dividend, \divisor, lsr #3
|
||||
orrhs \result, \result, \curbit, lsr #3
|
||||
cmp \dividend, #0 @ Early termination?
|
||||
movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
|
||||
movne \divisor, \divisor, lsr #4
|
||||
bne 1b
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
.macro ARM_DIV2_ORDER divisor, order
|
||||
|
||||
#if __LINUX_ARM_ARCH__ >= 5
|
||||
|
||||
clz \order, \divisor
|
||||
rsb \order, \order, #31
|
||||
|
||||
#else
|
||||
|
||||
cmp \divisor, #(1 << 16)
|
||||
movhs \divisor, \divisor, lsr #16
|
||||
movhs \order, #16
|
||||
movlo \order, #0
|
||||
|
||||
cmp \divisor, #(1 << 8)
|
||||
movhs \divisor, \divisor, lsr #8
|
||||
addhs \order, \order, #8
|
||||
|
||||
cmp \divisor, #(1 << 4)
|
||||
movhs \divisor, \divisor, lsr #4
|
||||
addhs \order, \order, #4
|
||||
|
||||
cmp \divisor, #(1 << 2)
|
||||
addhi \order, \order, #3
|
||||
addls \order, \order, \divisor, lsr #1
|
||||
|
||||
#endif
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
.macro ARM_MOD_BODY dividend, divisor, order, spare
|
||||
|
||||
#if __LINUX_ARM_ARCH__ >= 5
|
||||
|
||||
clz \order, \divisor
|
||||
clz \spare, \dividend
|
||||
sub \order, \order, \spare
|
||||
mov \divisor, \divisor, lsl \order
|
||||
|
||||
#else
|
||||
|
||||
mov \order, #0
|
||||
|
||||
@ Unless the divisor is very big, shift it up in multiples of
|
||||
@ four bits, since this is the amount of unwinding in the main
|
||||
@ division loop. Continue shifting until the divisor is
|
||||
@ larger than the dividend.
|
||||
1: cmp \divisor, #0x10000000
|
||||
cmplo \divisor, \dividend
|
||||
movlo \divisor, \divisor, lsl #4
|
||||
addlo \order, \order, #4
|
||||
blo 1b
|
||||
|
||||
@ For very big divisors, we must shift it a bit at a time, or
|
||||
@ we will be in danger of overflowing.
|
||||
1: cmp \divisor, #0x80000000
|
||||
cmplo \divisor, \dividend
|
||||
movlo \divisor, \divisor, lsl #1
|
||||
addlo \order, \order, #1
|
||||
blo 1b
|
||||
|
||||
#endif
|
||||
|
||||
@ Perform all needed substractions to keep only the reminder.
|
||||
@ Do comparisons in batch of 4 first.
|
||||
subs \order, \order, #3 @ yes, 3 is intended here
|
||||
blt 2f
|
||||
|
||||
1: cmp \dividend, \divisor
|
||||
subhs \dividend, \dividend, \divisor
|
||||
cmp \dividend, \divisor, lsr #1
|
||||
subhs \dividend, \dividend, \divisor, lsr #1
|
||||
cmp \dividend, \divisor, lsr #2
|
||||
subhs \dividend, \dividend, \divisor, lsr #2
|
||||
cmp \dividend, \divisor, lsr #3
|
||||
subhs \dividend, \dividend, \divisor, lsr #3
|
||||
cmp \dividend, #1
|
||||
mov \divisor, \divisor, lsr #4
|
||||
subges \order, \order, #4
|
||||
bge 1b
|
||||
|
||||
tst \order, #3
|
||||
teqne \dividend, #0
|
||||
beq 5f
|
||||
|
||||
@ Either 1, 2 or 3 comparison/substractions are left.
|
||||
2: cmn \order, #2
|
||||
blt 4f
|
||||
beq 3f
|
||||
cmp \dividend, \divisor
|
||||
subhs \dividend, \dividend, \divisor
|
||||
mov \divisor, \divisor, lsr #1
|
||||
3: cmp \dividend, \divisor
|
||||
subhs \dividend, \dividend, \divisor
|
||||
mov \divisor, \divisor, lsr #1
|
||||
4: cmp \dividend, \divisor
|
||||
subhs \dividend, \dividend, \divisor
|
||||
5:
|
||||
.endm
|
||||
|
||||
|
||||
#if 0
|
||||
ENTRY(__udivsi3)
|
||||
|
||||
subs r2, r1, #1
|
||||
moveq pc, lr
|
||||
bcc Ldiv0
|
||||
cmp r0, r1
|
||||
bls 11f
|
||||
tst r1, r2
|
||||
beq 12f
|
||||
|
||||
ARM_DIV_BODY r0, r1, r2, r3
|
||||
|
||||
mov r0, r2
|
||||
mov pc, lr
|
||||
|
||||
11: moveq r0, #1
|
||||
movne r0, #0
|
||||
mov pc, lr
|
||||
|
||||
12: ARM_DIV2_ORDER r1, r2
|
||||
|
||||
mov r0, r0, lsr r2
|
||||
mov pc, lr
|
||||
|
||||
#endif
|
||||
|
||||
ENTRY(__umodsi3)
|
||||
|
||||
subs r2, r1, #1 @ compare divisor with 1
|
||||
bcc Ldiv0
|
||||
cmpne r0, r1 @ compare dividend with divisor
|
||||
moveq r0, #0
|
||||
tsthi r1, r2 @ see if divisor is power of 2
|
||||
andeq r0, r0, r2
|
||||
movls pc, lr
|
||||
|
||||
ARM_MOD_BODY r0, r1, r2, r3
|
||||
|
||||
mov pc, lr
|
||||
|
||||
#if 0
|
||||
ENTRY(__divsi3)
|
||||
|
||||
cmp r1, #0
|
||||
eor ip, r0, r1 @ save the sign of the result.
|
||||
beq Ldiv0
|
||||
rsbmi r1, r1, #0 @ loops below use unsigned.
|
||||
subs r2, r1, #1 @ division by 1 or -1 ?
|
||||
beq 10f
|
||||
movs r3, r0
|
||||
rsbmi r3, r0, #0 @ positive dividend value
|
||||
cmp r3, r1
|
||||
bls 11f
|
||||
tst r1, r2 @ divisor is power of 2 ?
|
||||
beq 12f
|
||||
|
||||
ARM_DIV_BODY r3, r1, r0, r2
|
||||
|
||||
cmp ip, #0
|
||||
rsbmi r0, r0, #0
|
||||
mov pc, lr
|
||||
|
||||
10: teq ip, r0 @ same sign ?
|
||||
rsbmi r0, r0, #0
|
||||
mov pc, lr
|
||||
|
||||
11: movlo r0, #0
|
||||
moveq r0, ip, asr #31
|
||||
orreq r0, r0, #1
|
||||
mov pc, lr
|
||||
|
||||
12: ARM_DIV2_ORDER r1, r2
|
||||
|
||||
cmp ip, #0
|
||||
mov r0, r3, lsr r2
|
||||
rsbmi r0, r0, #0
|
||||
mov pc, lr
|
||||
#endif
|
||||
|
||||
ENTRY(__modsi3)
|
||||
|
||||
cmp r1, #0
|
||||
beq Ldiv0
|
||||
rsbmi r1, r1, #0 @ loops below use unsigned.
|
||||
movs ip, r0 @ preserve sign of dividend
|
||||
rsbmi r0, r0, #0 @ if negative make positive
|
||||
subs r2, r1, #1 @ compare divisor with 1
|
||||
cmpne r0, r1 @ compare dividend with divisor
|
||||
moveq r0, #0
|
||||
tsthi r1, r2 @ see if divisor is power of 2
|
||||
andeq r0, r0, r2
|
||||
bls 10f
|
||||
|
||||
ARM_MOD_BODY r0, r1, r2, r3
|
||||
|
||||
10: cmp ip, #0
|
||||
rsbmi r0, r0, #0
|
||||
mov pc, lr
|
||||
|
||||
|
||||
Ldiv0:
|
||||
|
||||
str lr, [sp, #-4]!
|
||||
/* bl __div0 */
|
||||
mov r0, #0 @ About as wrong as it could be.
|
||||
ldr pc, [sp], #4
|
||||
|
77
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/muldi3.c
Normal file
77
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/muldi3.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/* More subroutines needed by GCC output code on some machines. */
|
||||
/* Compile this one with gcc. */
|
||||
/* Copyright (C) 1989, 92-98, 1999 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 License 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 License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
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. */
|
||||
|
||||
/* As a special exception, if you link this library with other files,
|
||||
some of which are compiled with GCC, to produce an executable,
|
||||
this library does not by itself cause the resulting executable
|
||||
to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public License.
|
||||
*/
|
||||
/* support functions required by the kernel. based on code from gcc-2.95.3 */
|
||||
/* I Molton 29/07/01 */
|
||||
|
||||
#include "gcclib.h"
|
||||
|
||||
#define umul_ppmm(xh, xl, a, b) \
|
||||
{register USItype __t0, __t1, __t2; \
|
||||
__asm__ ("%@ Inlined umul_ppmm \n\
|
||||
mov %2, %5, lsr #16 \n\
|
||||
mov %0, %6, lsr #16 \n\
|
||||
bic %3, %5, %2, lsl #16 \n\
|
||||
bic %4, %6, %0, lsl #16 \n\
|
||||
mul %1, %3, %4 \n\
|
||||
mul %4, %2, %4 \n\
|
||||
mul %3, %0, %3 \n\
|
||||
mul %0, %2, %0 \n\
|
||||
adds %3, %4, %3 \n\
|
||||
addcs %0, %0, #65536 \n\
|
||||
adds %1, %1, %3, lsl #16 \n\
|
||||
adc %0, %0, %3, lsr #16" \
|
||||
: "=&r" ((USItype) (xh)), \
|
||||
"=r" ((USItype) (xl)), \
|
||||
"=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
|
||||
: "r" ((USItype) (a)), \
|
||||
"r" ((USItype) (b)));}
|
||||
|
||||
|
||||
#define __umulsidi3(u, v) \
|
||||
({DIunion __w; \
|
||||
umul_ppmm (__w.s.high, __w.s.low, u, v); \
|
||||
__w.ll; })
|
||||
|
||||
|
||||
DItype
|
||||
__muldi3 (DItype u, DItype v)
|
||||
{
|
||||
DIunion w;
|
||||
DIunion uu, vv;
|
||||
|
||||
uu.ll = u,
|
||||
vv.ll = v;
|
||||
|
||||
w.ll = __umulsidi3 (uu.s.low, vv.s.low);
|
||||
w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
|
||||
+ (USItype) uu.s.high * (USItype) vv.s.low);
|
||||
|
||||
return w.ll;
|
||||
}
|
||||
|
60
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/printf.c
Normal file
60
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/printf.c
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "vsprintf.h"
|
||||
#include "string.h"
|
||||
#include "printf.h"
|
||||
#include "bsp_uart.h"
|
||||
|
||||
extern void uart_putc(unsigned char c);
|
||||
extern unsigned char uart_getc(void);
|
||||
|
||||
#define OUTBUFSIZE 1024
|
||||
#define INBUFSIZE 1024
|
||||
|
||||
|
||||
static char g_pcOutBuf[OUTBUFSIZE];
|
||||
static char g_pcInBuf[INBUFSIZE];
|
||||
|
||||
|
||||
int printf(const char *fmt, ...)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
len = vsprintf(g_pcOutBuf,fmt,args);
|
||||
va_end(args);
|
||||
for (i = 0; i < strlen(g_pcOutBuf); i++)
|
||||
{
|
||||
uart_putc(g_pcOutBuf[i]);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int scanf(const char * fmt, ...)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned char c;
|
||||
va_list args;
|
||||
|
||||
while(1)
|
||||
{
|
||||
c = uart_getc();
|
||||
uart_putc(c);
|
||||
if((c == 0x0d) || (c == 0x0a))
|
||||
{
|
||||
g_pcInBuf[i] = '\0';
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pcInBuf[i++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
va_start(args,fmt);
|
||||
i = vsscanf(g_pcInBuf,fmt,args);
|
||||
va_end(args);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
533
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/string.c
Normal file
533
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/string.c
Normal file
@@ -0,0 +1,533 @@
|
||||
/*
|
||||
* linux/lib/string.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
/*
|
||||
* stupid library routines.. The optimized versions should generally be found
|
||||
* as inline code in <asm-xx/string.h>
|
||||
*
|
||||
* These are buggy as well..
|
||||
*
|
||||
* * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
|
||||
* - Added strsep() which will replace strtok() soon (because strsep() is
|
||||
* reentrant and should be faster). Use only strsep() in new code, please.
|
||||
*/
|
||||
//#include <linux/types.h>
|
||||
//#include <linux/string.h>
|
||||
//#include "types.h"
|
||||
#include "ctype.h"
|
||||
#include "string.h"
|
||||
|
||||
#ifndef __HAVE_ARCH_STRNICMP
|
||||
/**
|
||||
* strnicmp - Case insensitive, length-limited string comparison
|
||||
* @s1: One string
|
||||
* @s2: The other string
|
||||
* @len: the maximum number of characters to compare
|
||||
*/
|
||||
int strnicmp(const char *s1, const char *s2, size_t len)
|
||||
{
|
||||
/* Yes, Virginia, it had better be unsigned */
|
||||
unsigned char c1, c2;
|
||||
|
||||
c1 = 0; c2 = 0;
|
||||
if (len) {
|
||||
do {
|
||||
c1 = *s1; c2 = *s2;
|
||||
s1++; s2++;
|
||||
if (!c1)
|
||||
break;
|
||||
if (!c2)
|
||||
break;
|
||||
if (c1 == c2)
|
||||
continue;
|
||||
c1 = tolower(c1);
|
||||
c2 = tolower(c2);
|
||||
if (c1 != c2)
|
||||
break;
|
||||
} while (--len);
|
||||
}
|
||||
return (int)c1 - (int)c2;
|
||||
}
|
||||
#endif
|
||||
|
||||
char * ___strtok;
|
||||
|
||||
#ifndef __HAVE_ARCH_STRCPY
|
||||
/**
|
||||
* strcpy - Copy a %NUL terminated string
|
||||
* @dest: Where to copy the string to
|
||||
* @src: Where to copy the string from
|
||||
*/
|
||||
char * strcpy(char * dest,const char *src)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while ((*dest++ = *src++) != '\0')
|
||||
/* nothing */;
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRNCPY
|
||||
/**
|
||||
* strncpy - Copy a length-limited, %NUL-terminated string
|
||||
* @dest: Where to copy the string to
|
||||
* @src: Where to copy the string from
|
||||
* @count: The maximum number of bytes to copy
|
||||
*
|
||||
* Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
|
||||
* However, the result is not %NUL-terminated if the source exceeds
|
||||
* @count bytes.
|
||||
*/
|
||||
char * strncpy(char * dest,const char *src,size_t count)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while (count-- && (*dest++ = *src++) != '\0')
|
||||
/* nothing */;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRCAT
|
||||
/**
|
||||
* strcat - Append one %NUL-terminated string to another
|
||||
* @dest: The string to be appended to
|
||||
* @src: The string to append to it
|
||||
*/
|
||||
char * strcat(char * dest, const char * src)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while (*dest)
|
||||
dest++;
|
||||
while ((*dest++ = *src++) != '\0')
|
||||
;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRNCAT
|
||||
/**
|
||||
* strncat - Append a length-limited, %NUL-terminated string to another
|
||||
* @dest: The string to be appended to
|
||||
* @src: The string to append to it
|
||||
* @count: The maximum numbers of bytes to copy
|
||||
*
|
||||
* Note that in contrast to strncpy, strncat ensures the result is
|
||||
* terminated.
|
||||
*/
|
||||
char * strncat(char *dest, const char *src, size_t count)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
if (count) {
|
||||
while (*dest)
|
||||
dest++;
|
||||
while ((*dest++ = *src++)) {
|
||||
if (--count == 0) {
|
||||
*dest = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRCMP
|
||||
/**
|
||||
* strcmp - Compare two strings
|
||||
* @cs: One string
|
||||
* @ct: Another string
|
||||
*/
|
||||
int strcmp(const char * cs,const char * ct)
|
||||
{
|
||||
register signed char __res;
|
||||
|
||||
while (1) {
|
||||
if ((__res = *cs - *ct++) != 0 || !*cs++)
|
||||
break;
|
||||
}
|
||||
|
||||
return __res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRNCMP
|
||||
/**
|
||||
* strncmp - Compare two length-limited strings
|
||||
* @cs: One string
|
||||
* @ct: Another string
|
||||
* @count: The maximum number of bytes to compare
|
||||
*/
|
||||
int strncmp(const char * cs,const char * ct,size_t count)
|
||||
{
|
||||
register signed char __res = 0;
|
||||
|
||||
while (count) {
|
||||
if ((__res = *cs - *ct++) != 0 || !*cs++)
|
||||
break;
|
||||
count--;
|
||||
}
|
||||
|
||||
return __res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRCHR
|
||||
/**
|
||||
* strchr - Find the first occurrence of a character in a string
|
||||
* @s: The string to be searched
|
||||
* @c: The character to search for
|
||||
*/
|
||||
char * strchr(const char * s, int c)
|
||||
{
|
||||
for(; *s != (char) c; ++s)
|
||||
if (*s == '\0')
|
||||
return NULL;
|
||||
return (char *) s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRRCHR
|
||||
/**
|
||||
* strrchr - Find the last occurrence of a character in a string
|
||||
* @s: The string to be searched
|
||||
* @c: The character to search for
|
||||
*/
|
||||
char * strrchr(const char * s, int c)
|
||||
{
|
||||
const char *p = s + strlen(s);
|
||||
do {
|
||||
if (*p == (char)c)
|
||||
return (char *)p;
|
||||
} while (--p >= s);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRLEN
|
||||
/**
|
||||
* strlen - Find the length of a string
|
||||
* @s: The string to be sized
|
||||
*/
|
||||
size_t strlen(const char * s)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for (sc = s; *sc != '\0'; ++sc)
|
||||
/* nothing */;
|
||||
return sc - s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRNLEN
|
||||
/**
|
||||
* strnlen - Find the length of a length-limited string
|
||||
* @s: The string to be sized
|
||||
* @count: The maximum number of bytes to search
|
||||
*/
|
||||
size_t strnlen(const char * s, size_t count)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for (sc = s; count-- && *sc != '\0'; ++sc)
|
||||
/* nothing */;
|
||||
return sc - s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSPN
|
||||
/**
|
||||
* strspn - Calculate the length of the initial substring of @s which only
|
||||
* contain letters in @accept
|
||||
* @s: The string to be searched
|
||||
* @accept: The string to search for
|
||||
*/
|
||||
size_t strspn(const char *s, const char *accept)
|
||||
{
|
||||
const char *p;
|
||||
const char *a;
|
||||
size_t count = 0;
|
||||
|
||||
for (p = s; *p != '\0'; ++p) {
|
||||
for (a = accept; *a != '\0'; ++a) {
|
||||
if (*p == *a)
|
||||
break;
|
||||
}
|
||||
if (*a == '\0')
|
||||
return count;
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRPBRK
|
||||
/**
|
||||
* strpbrk - Find the first occurrence of a set of characters
|
||||
* @cs: The string to be searched
|
||||
* @ct: The characters to search for
|
||||
*/
|
||||
char * strpbrk(const char * cs,const char * ct)
|
||||
{
|
||||
const char *sc1,*sc2;
|
||||
|
||||
for( sc1 = cs; *sc1 != '\0'; ++sc1) {
|
||||
for( sc2 = ct; *sc2 != '\0'; ++sc2) {
|
||||
if (*sc1 == *sc2)
|
||||
return (char *) sc1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRTOK
|
||||
/**
|
||||
* strtok - Split a string into tokens
|
||||
* @s: The string to be searched
|
||||
* @ct: The characters to search for
|
||||
*
|
||||
* WARNING: strtok is deprecated, use strsep instead.
|
||||
*/
|
||||
char * strtok(char * s,const char * ct)
|
||||
{
|
||||
char *sbegin, *send;
|
||||
|
||||
sbegin = s ? s : ___strtok;
|
||||
if (!sbegin) {
|
||||
return NULL;
|
||||
}
|
||||
sbegin += strspn(sbegin,ct);
|
||||
if (*sbegin == '\0') {
|
||||
___strtok = NULL;
|
||||
return( NULL );
|
||||
}
|
||||
send = strpbrk( sbegin, ct);
|
||||
if (send && *send != '\0')
|
||||
*send++ = '\0';
|
||||
___strtok = send;
|
||||
return (sbegin);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSEP
|
||||
/**
|
||||
* strsep - Split a string into tokens
|
||||
* @s: The string to be searched
|
||||
* @ct: The characters to search for
|
||||
*
|
||||
* strsep() updates @s to point after the token, ready for the next call.
|
||||
*
|
||||
* It returns empty tokens, too, behaving exactly like the libc function
|
||||
* of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
|
||||
* Same semantics, slimmer shape. ;)
|
||||
*/
|
||||
char * strsep(char **s, const char *ct)
|
||||
{
|
||||
char *sbegin = *s, *end;
|
||||
|
||||
if (sbegin == NULL)
|
||||
return NULL;
|
||||
|
||||
end = strpbrk(sbegin, ct);
|
||||
if (end)
|
||||
*end++ = '\0';
|
||||
*s = end;
|
||||
|
||||
return sbegin;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMSET
|
||||
/**
|
||||
* memset - Fill a region of memory with the given value
|
||||
* @s: Pointer to the start of the area.
|
||||
* @c: The byte to fill the area with
|
||||
* @count: The size of the area.
|
||||
*
|
||||
* Do not use memset() to access IO space, use memset_io() instead.
|
||||
*/
|
||||
void * memset(void * s,int c,size_t count)
|
||||
{
|
||||
char *xs = (char *) s;
|
||||
|
||||
while (count--)
|
||||
*xs++ = c;
|
||||
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_BCOPY
|
||||
/**
|
||||
* bcopy - Copy one area of memory to another
|
||||
* @src: Where to copy from
|
||||
* @dest: Where to copy to
|
||||
* @count: The size of the area.
|
||||
*
|
||||
* Note that this is the same as memcpy(), with the arguments reversed.
|
||||
* memcpy() is the standard, bcopy() is a legacy BSD function.
|
||||
*
|
||||
* You should not use this function to access IO space, use memcpy_toio()
|
||||
* or memcpy_fromio() instead.
|
||||
*/
|
||||
void bcopy(const void *src, void *dest, size_t count)
|
||||
{
|
||||
char *destTmp = (char *)dest;
|
||||
char *srcTmp = (char *)src;
|
||||
|
||||
while (count--)
|
||||
*destTmp++ = *srcTmp++;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMCPY
|
||||
/**
|
||||
* memcpy - Copy one area of memory to another
|
||||
* @dest: Where to copy to
|
||||
* @src: Where to copy from
|
||||
* @count: The size of the area.
|
||||
*
|
||||
* You should not use this function to access IO space, use memcpy_toio()
|
||||
* or memcpy_fromio() instead.
|
||||
*/
|
||||
void * memcpy(void * dest,const void *src,size_t count)
|
||||
{
|
||||
char *tmp = (char *) dest, *s = (char *) src;
|
||||
|
||||
while (count--)
|
||||
*tmp++ = *s++;
|
||||
|
||||
return dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMMOVE
|
||||
/**
|
||||
* memmove - Copy one area of memory to another
|
||||
* @dest: Where to copy to
|
||||
* @src: Where to copy from
|
||||
* @count: The size of the area.
|
||||
*
|
||||
* Unlike memcpy(), memmove() copes with overlapping areas.
|
||||
*/
|
||||
void * memmove(void * dest,const void *src,size_t count)
|
||||
{
|
||||
char *tmp, *s;
|
||||
|
||||
if (dest <= src) {
|
||||
tmp = (char *) dest;
|
||||
s = (char *) src;
|
||||
while (count--)
|
||||
*tmp++ = *s++;
|
||||
}
|
||||
else {
|
||||
tmp = (char *) dest + count;
|
||||
s = (char *) src + count;
|
||||
while (count--)
|
||||
*--tmp = *--s;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMCMP
|
||||
/**
|
||||
* memcmp - Compare two areas of memory
|
||||
* @cs: One area of memory
|
||||
* @ct: Another area of memory
|
||||
* @count: The size of the area.
|
||||
*/
|
||||
int memcmp(const void * cs,const void * ct,size_t count)
|
||||
{
|
||||
const unsigned char *su1, *su2;
|
||||
int res = 0;
|
||||
|
||||
for( su1 = (const unsigned char *)cs, su2 = (const unsigned char *)ct; 0 < count; ++su1, ++su2, count--)
|
||||
if ((res = *su1 - *su2) != 0)
|
||||
break;
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMSCAN
|
||||
/**
|
||||
* memscan - Find a character in an area of memory.
|
||||
* @addr: The memory area
|
||||
* @c: The byte to search for
|
||||
* @size: The size of the area.
|
||||
*
|
||||
* returns the address of the first occurrence of @c, or 1 byte past
|
||||
* the area if @c is not found
|
||||
*/
|
||||
void * memscan(void * addr, int c, size_t size)
|
||||
{
|
||||
unsigned char * p = (unsigned char *) addr;
|
||||
|
||||
while (size) {
|
||||
if (*p == c)
|
||||
return (void *) p;
|
||||
p++;
|
||||
size--;
|
||||
}
|
||||
return (void *) p;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSTR
|
||||
/**
|
||||
* strstr - Find the first substring in a %NUL terminated string
|
||||
* @s1: The string to be searched
|
||||
* @s2: The string to search for
|
||||
*/
|
||||
char * strstr(const char * s1,const char * s2)
|
||||
{
|
||||
int l1, l2;
|
||||
|
||||
l2 = strlen(s2);
|
||||
if (!l2)
|
||||
return (char *) s1;
|
||||
l1 = strlen(s1);
|
||||
while (l1 >= l2) {
|
||||
l1--;
|
||||
if (!memcmp(s1,s2,l2))
|
||||
return (char *) s1;
|
||||
s1++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMCHR
|
||||
/**
|
||||
* memchr - Find a character in an area of memory.
|
||||
* @s: The memory area
|
||||
* @c: The byte to search for
|
||||
* @n: The size of the area.
|
||||
*
|
||||
* returns the address of the first occurrence of @c, or %NULL
|
||||
* if @c is not found
|
||||
*/
|
||||
void *memchr(const void *s, int c, size_t n)
|
||||
{
|
||||
const unsigned char *p = (const unsigned char *)s;
|
||||
while (n-- != 0) {
|
||||
if ((unsigned char)c == *p++) {
|
||||
return (void *)(p-1);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
1066
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/vsprintf.c
Normal file
1066
board/ALPHA_I.MX_emmc_256ddr/stdio/lib/vsprintf.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user