summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Albrecht <prom@berlin.ccc.de>2010-07-15 20:30:44 +0200
committerIngo Albrecht <prom@berlin.ccc.de>2010-08-17 00:29:08 +0200
commit0829532cb8c653cbf5d1242e50d548bd296bc81f (patch)
tree1ebf19b3bbc1d82b95897eaae02829142c6bd733
parentff7ce383a16d4eeede22039873f060341630294a (diff)
firmware: switched from libmini to dietlibc
-rw-r--r--src/Makefile7
-rw-r--r--src/target/firmware/Makefile5
-rw-r--r--src/target/firmware/Makefile.inc8
-rw-r--r--src/target/firmware/comm/sercomm_cons.c30
-rw-r--r--src/target/firmware/display/ssd1783.c2
-rw-r--r--src/target/firmware/display/st7558.c2
-rw-r--r--src/target/firmware/include/comm/sercomm_cons.h3
-rw-r--r--src/target/firmware/include/display.h4
-rw-r--r--src/target/firmware/include/stdint.h29
-rw-r--r--src/target/firmware/include/stdio.h52
-rw-r--r--src/target/firmware/include/string.h12
-rw-r--r--src/target/firmware/lib/Makefile4
-rw-r--r--src/target/firmware/lib/copy_template.S255
-rw-r--r--src/target/firmware/lib/ctype.c34
-rw-r--r--src/target/firmware/lib/lib1funcs.S334
-rw-r--r--src/target/firmware/lib/memcpy.S59
-rw-r--r--src/target/firmware/lib/memset.S80
-rw-r--r--src/target/firmware/lib/printf.c19
-rw-r--r--src/target/firmware/lib/string.c50
-rw-r--r--src/target/firmware/lib/system.c42
-rw-r--r--src/target/firmware/lib/vsprintf.c847
21 files changed, 80 insertions, 1798 deletions
diff --git a/src/Makefile b/src/Makefile
index 6d16b7d6..75d3a554 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -12,7 +12,7 @@ OSMOCORE_CONFIGURE_ENV= LIBOSMOCORE_LIBS=$(TOPDIR)/shared/libosmocore/build-host
LIBOSMOCORE_CFLAGS=-I$(TOPDIR)/shared/libosmocore/include \
LIBOSMOVTY_CFLAGS=-I$(TOPDIR)/shared/libosmocore/include
-all: libosmocore-host libosmocore-target layer23 osmocon firmware
+all: libosmocore-host libosmocore-target layer23 osmocon dietlibc firmware
libosmocore-host: shared/libosmocore/build-host/src/.libs/libosmocore.la
@@ -69,6 +69,9 @@ host/layer23/Makefile: host/layer23/configure
host/layer23/layer23: host/layer23/Makefile libosmocore-host
make -C host/layer23
+.PHONY: dietlibc
+dietlibc:
+ make -C target/dietlibc
.PHONY: firmware
firmware: libosmocore-target
@@ -80,6 +83,7 @@ clean:
make -C shared/libosmocore/build-target $@
make -C host/layer23 $@
make -C host/osmocon $@
+ make -C target/dietlibc $@
make -C target/firmware $@
distclean:
@@ -87,4 +91,5 @@ distclean:
rm -rf shared/libosmocore/build-target
make -C host/layer23 $@
make -C host/osmocon $@
+ make -C target/dietlibc clean # always distclean
make -C target/firmware $@
diff --git a/src/target/firmware/Makefile b/src/target/firmware/Makefile
index b5fcf995..30055398 100644
--- a/src/target/firmware/Makefile
+++ b/src/target/firmware/Makefile
@@ -1,5 +1,4 @@
-
# List of all supported boards (meant to be overridden on command line)
BOARDS?=compal_e88 compal_e99 gta0x
@@ -50,7 +49,7 @@ e99loader_OBJS=board/compal/header.o
e99flash_LDS=board/compal_e99/flash.lds
# Global include path
-INCLUDES=-Iinclude/ -I../../../include -I../../shared/libosmocore/include
+INCLUDES=-Iinclude/ -I../../../include -I../dietlibc/include -I../../shared/libosmocore/include
# Various objects that are currently linked into all applications
FLASH_OBJS=flash/cfi_flash.o
@@ -60,7 +59,7 @@ RF_OBJS=rf/trf6151.o
# Objects that go in all applications
ANY_APP_OBJS+=$(ABB_OBJS) $(RF_OBJS) $(DISPLAY_OBJS) $(FLASH_OBJS)
-ANY_APP_LIBS+=calypso/libcalypso.a layer1/liblayer1.a lib/libmini.a comm/libcomm.a ../../shared/libosmocore/build-target/src/.libs/libosmocore.a
+ANY_APP_LIBS+=calypso/libcalypso.a layer1/liblayer1.a lib/libmini.a comm/libcomm.a ../dietlibc/bin-arm/dietlibc.a ../../shared/libosmocore/build-target/src/.libs/libosmocore.a
# Libraries are defined in subdirectories
diff --git a/src/target/firmware/Makefile.inc b/src/target/firmware/Makefile.inc
index 11c63ec8..5f1542d0 100644
--- a/src/target/firmware/Makefile.inc
+++ b/src/target/firmware/Makefile.inc
@@ -22,7 +22,7 @@ CFLAGS += -g$(DEBUGF)
#ASFLAGS=--g$(DEBUGF) $(INCLUDES) -D__ASSEMBLY__
ASFLAGS=$(INCLUDES) -D__ASSEMBLY__
-LDFLAGS = -nostartfiles -nostdlib -nodefaultlibs --gc-sections --cref
+LDFLAGS = -static -static-libgcc -nostartfiles -nostdlib -nodefaultlibs -Wl,--gc-sections -Wl,--cref
#### GIT VERSION ####
@@ -82,9 +82,9 @@ $(1)_$(2)_$(3)_OBJS+=board/$(2)/$(1).$(3).manifest.o $$($(3)_OBJS)
# define compilation rule, also generates map file
board/$(2)/$(1).$(3).elf board/$(2)/$(1).$(3).map: $$($(1)_$(2)_$(3)_OBJS) $$($(1)_$(2)_$(3)_LIBS) $$($(3)_LDS)
- $(CROSS_COMPILE)$(LD) $(LDFLAGS) -T $$($(3)_LDS) -Bstatic \
- -Map board/$(2)/$(1).$(3).map -o board/$(2)/$(1).$(3).elf \
- --start-group $$($(1)_$(2)_$(3)_OBJS) $$($(1)_$(2)_$(3)_LIBS) --end-group
+ $(CROSS_COMPILE)$(CC) $(LDFLAGS) -T $$($(3)_LDS) \
+ -Wl,-Map="board/$(2)/$(1).$(3).map" -o board/$(2)/$(1).$(3).elf \
+ -Wl,--start-group -lgcc $$($(1)_$(2)_$(3)_OBJS) $$($(1)_$(2)_$(3)_LIBS) -Wl,--end-group
# define size rule
board/$(2)/$(1).$(3).size: board/$(2)/$(1).$(3).elf
diff --git a/src/target/firmware/comm/sercomm_cons.c b/src/target/firmware/comm/sercomm_cons.c
index 5d7842fb..dd833e42 100644
--- a/src/target/firmware/comm/sercomm_cons.c
+++ b/src/target/firmware/comm/sercomm_cons.c
@@ -50,16 +50,15 @@ static void raw_puts(const char *s)
#define raw_putd(x)
#endif
-int sercomm_puts(const char *s)
+int sercomm_write(const char *s, const int len)
{
unsigned long flags;
- const int len = strlen(s);
unsigned int bytes_left = len;
if (!sercomm_initialized()) {
raw_putd("sercomm not initialized: ");
raw_puts(s);
- return len - 1;
+ return len;
}
/* This function is called from any context: Supervisor, IRQ, FIQ, ...
@@ -112,27 +111,34 @@ int sercomm_puts(const char *s)
bytes_left -= write_num;
if (flush) {
- sercomm_sendmsg(SC_DLCI_CONSOLE, scons.cur_msg);
- /* reset scons.cur_msg pointer to ensure we allocate
- * a new one next round */
- scons.cur_msg = NULL;
+ sercomm_flush();
}
}
local_irq_restore(flags);
- return len - 1;
+ sercomm_flush();
+
+ return len;
+}
+
+void sercomm_flush()
+{
+ if(scons.cur_msg) {
+ sercomm_sendmsg(SC_DLCI_CONSOLE, scons.cur_msg);
+ /* reset scons.cur_msg pointer to ensure we allocate
+ * a new one next round */
+ scons.cur_msg = NULL;
+ }
}
int sercomm_putchar(int c)
{
- char s[2];
+ char xc = c & 0xFF;
int rc;
- s[0] = c & 0xff;
- s[1] = '\0';
+ rc = sercomm_write(&xc, 1);
- rc = sercomm_puts(s);
if (rc < 0)
return rc;
diff --git a/src/target/firmware/display/ssd1783.c b/src/target/firmware/display/ssd1783.c
index 5696b48f..98f7c357 100644
--- a/src/target/firmware/display/ssd1783.c
+++ b/src/target/firmware/display/ssd1783.c
@@ -252,6 +252,6 @@ const struct display_driver ssd1783_display = {
.unset_attr = &ssd1783_set_attr,
.clrscr = &ssd1783_clrscr,
.goto_xy = &ssd1783_goto_xy,
- .putc = &ssd1783_putc,
+ .putchr = &ssd1783_putc,
.puts = &ssd1783_puts,
};
diff --git a/src/target/firmware/display/st7558.c b/src/target/firmware/display/st7558.c
index baed9eb0..ca22daa0 100644
--- a/src/target/firmware/display/st7558.c
+++ b/src/target/firmware/display/st7558.c
@@ -119,5 +119,5 @@ const struct display_driver st7558_display = {
.clrscr = &st7558_clrscr,
.set_attr = &st7558_set_attr,
.unset_attr = &st7558_unset_attr,
- .putc = &st7558_putc,
+ .putchr = &st7558_putc,
};
diff --git a/src/target/firmware/include/comm/sercomm_cons.h b/src/target/firmware/include/comm/sercomm_cons.h
index 11f66545..179bf77d 100644
--- a/src/target/firmware/include/comm/sercomm_cons.h
+++ b/src/target/firmware/include/comm/sercomm_cons.h
@@ -4,7 +4,8 @@
/* how large buffers do we allocate? */
#define SERCOMM_CONS_ALLOC 256
-int sercomm_puts(const char *s);
+int sercomm_write(const char *s, const int len);
int sercomm_putchar(int c);
+void sercomm_flush();
#endif /* _SERCOMM_CONS_H */
diff --git a/src/target/firmware/include/display.h b/src/target/firmware/include/display.h
index 89d02a57..c2b614e7 100644
--- a/src/target/firmware/include/display.h
+++ b/src/target/firmware/include/display.h
@@ -13,7 +13,7 @@ struct display_driver {
void (*clrscr)(void);
void (*goto_xy)(int xpos, int ypos);
void (*set_color)(int fgcolor, int bgcolor);
- int (*putc)(unsigned char c);
+ int (*putchr)(unsigned char c);
int (*puts)(const char *str);
};
@@ -37,7 +37,7 @@ static inline void display_clrscr(void)
}
static inline int display_putchar(unsigned char c)
{
- return display->putc(c);
+ return display->putchr(c);
}
int display_puts(const char *s);
diff --git a/src/target/firmware/include/stdint.h b/src/target/firmware/include/stdint.h
deleted file mode 100644
index 96907992..00000000
--- a/src/target/firmware/include/stdint.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef OSMO_STDINT_H
-#define OSMO_STDINT_H
-
-/* some older toolchains (like gnuarm-3.x) don't provide a C99
- compliant stdint.h yet, so we define our own here */
-
-/* to make matters worse newer gcc with glibc headers have
- a incompatible definition of these types. We will use the
- gcc'ism of #include_next to include the compiler's libc
- header file and then check if it has defined int8_t and
- if not we will use our own typedefs */
-
-#include_next <stdint.h>
-
-#ifndef __int8_t_defined
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
-
-typedef signed short int16_t;
-typedef unsigned short uint16_t;
-
-typedef signed int int32_t;
-typedef unsigned int uint32_t;
-
-typedef long long int int64_t;
-typedef unsigned long long int uint64_t;
-#endif
-
-#endif
diff --git a/src/target/firmware/include/stdio.h b/src/target/firmware/include/stdio.h
deleted file mode 100644
index 15ed6688..00000000
--- a/src/target/firmware/include/stdio.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef _STDIO_H
-#define _STDIO_H
-
-#ifndef NULL
-#define NULL 0
-#endif /* NULL */
-
-#include <sys/types.h>
-
-int printf(const char *format, ...);
-int sprintf(char *str, const char *format, ...);
-int snprintf(char *str, size_t size, const char *format, ...);
-
-#include <stdarg.h>
-
-int vprintf(const char *format, va_list ap);
-int vsprintf(char *str, const char *format, va_list ap);
-int vsnprintf(char *str, size_t size, const char *format, va_list ap);
-int puts(const char *s);
-
-#if 0
-/* start.S based uart console */
-#include <calypso/uart.h>
-#define putchar(c) uart_putchar_wait(1, c)
-int puts(const char *s);
-#endif
-
-#if 0
-/* regular UART console */
-#include <console.h>
-#define putchar(c) cons_putchar(c)
-#define _puts(s) cons_puts(s)
-#define ARCH_HAS_CONSOLE
-#endif
-
-#if 1
-/* sercomm based console */
-#include <comm/sercomm_cons.h>
-#define putchar(c) sercomm_putchar(c)
-#define _puts(s) sercomm_puts(s)
-#define ARCH_HAS_CONSOLE
-#endif
-
-struct __file {
-};
-
-typedef struct __file FILE;
-
-/* non-standard */
-extern void phex(unsigned int c, unsigned int len);
-
-#endif /* _STDIO_H */
diff --git a/src/target/firmware/include/string.h b/src/target/firmware/include/string.h
deleted file mode 100644
index f060659a..00000000
--- a/src/target/firmware/include/string.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _STRING_H
-#define _STRING_H
-
-#include <sys/types.h>
-
-size_t strnlen(const char *s, size_t count);
-size_t strlen(const char *s);
-
-void *memset(void *s, int c, size_t n);
-void *memcpy(void *dest, const void *src, size_t n);
-
-#endif
diff --git a/src/target/firmware/lib/Makefile b/src/target/firmware/lib/Makefile
index 987857c9..b7cb061e 100644
--- a/src/target/firmware/lib/Makefile
+++ b/src/target/firmware/lib/Makefile
@@ -1,7 +1,7 @@
LIBRARIES+=mini
mini_DIR=lib
-mini_SRCS=vsprintf.c string.c ctype.c printf.c console.c ctors.c \
- changebit.S clearbit.S div64.S lib1funcs.S memcpy.S memset.S setbit.S testchangebit.S testclearbit.S testsetbit.S
+mini_SRCS=system.c console.c ctors.c \
+ changebit.S clearbit.S setbit.S testchangebit.S testclearbit.S testsetbit.S
diff --git a/src/target/firmware/lib/copy_template.S b/src/target/firmware/lib/copy_template.S
deleted file mode 100644
index cab355c0..00000000
--- a/src/target/firmware/lib/copy_template.S
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * linux/arch/arm/lib/copy_template.s
- *
- * Code template for optimized memory copy functions
- *
- * Author: Nicolas Pitre
- * Created: Sep 28, 2005
- * Copyright: MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/*
- * This can be used to enable code to cacheline align the source pointer.
- * Experiments on tested architectures (StrongARM and XScale) didn't show
- * this a worthwhile thing to do. That might be different in the future.
- */
-//#define CALGN(code...) code
-#define CALGN(code...)
-
-/*
- * Theory of operation
- * -------------------
- *
- * This file provides the core code for a forward memory copy used in
- * the implementation of memcopy(), copy_to_user() and copy_from_user().
- *
- * The including file must define the following accessor macros
- * according to the need of the given function:
- *
- * ldr1w ptr reg abort
- *
- * This loads one word from 'ptr', stores it in 'reg' and increments
- * 'ptr' to the next word. The 'abort' argument is used for fixup tables.
- *
- * ldr4w ptr reg1 reg2 reg3 reg4 abort
- * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
- *
- * This loads four or eight words starting from 'ptr', stores them
- * in provided registers and increments 'ptr' past those words.
- * The'abort' argument is used for fixup tables.
- *
- * ldr1b ptr reg cond abort
- *
- * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
- * It also must apply the condition code if provided, otherwise the
- * "al" condition is assumed by default.
- *
- * str1w ptr reg abort
- * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
- * str1b ptr reg cond abort
- *
- * Same as their ldr* counterparts, but data is stored to 'ptr' location
- * rather than being loaded.
- *
- * enter reg1 reg2
- *
- * Preserve the provided registers on the stack plus any additional
- * data as needed by the implementation including this code. Called
- * upon code entry.
- *
- * exit reg1 reg2
- *
- * Restore registers with the values previously saved with the
- * 'preserv' macro. Called upon code termination.
- */
-
-
- enter r4, lr
-
- subs r2, r2, #4
- blt 8f
- ands ip, r0, #3
- PLD( pld [r1, #0] )
- bne 9f
- ands ip, r1, #3
- bne 10f
-
-1: subs r2, r2, #(28)
- stmfd sp!, {r5 - r8}
- blt 5f
-
- CALGN( ands ip, r1, #31 )
- CALGN( rsb r3, ip, #32 )
- CALGN( sbcnes r4, r3, r2 ) @ C is always set here
- CALGN( bcs 2f )
- CALGN( adr r4, 6f )
- CALGN( subs r2, r2, r3 ) @ C gets set
- CALGN( add pc, r4, ip )
-
- PLD( pld [r1, #0] )
-2: PLD( subs r2, r2, #96 )
- PLD( pld [r1, #28] )
- PLD( blt 4f )
- PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
-
-3: PLD( pld [r1, #124] )
-4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
- subs r2, r2, #32
- str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
- bge 3b
- PLD( cmn r2, #96 )
- PLD( bge 4b )
-
-5: ands ip, r2, #28
- rsb ip, ip, #32
- addne pc, pc, ip @ C is always clear here
- b 7f
-6: nop
- ldr1w r1, r3, abort=20f
- ldr1w r1, r4, abort=20f
- ldr1w r1, r5, abort=20f
- ldr1w r1, r6, abort=20f
- ldr1w r1, r7, abort=20f
- ldr1w r1, r8, abort=20f
- ldr1w r1, lr, abort=20f
-
- add pc, pc, ip
- nop
- nop
- str1w r0, r3, abort=20f
- str1w r0, r4, abort=20f
- str1w r0, r5, abort=20f
- str1w r0, r6, abort=20f
- str1w r0, r7, abort=20f
- str1w r0, r8, abort=20f
- str1w r0, lr, abort=20f
-
- CALGN( bcs 2b )
-
-7: ldmfd sp!, {r5 - r8}
-
-8: movs r2, r2, lsl #31
- ldr1b r1, r3, ne, abort=21f
- ldr1b r1, r4, cs, abort=21f
- ldr1b r1, ip, cs, abort=21f
- str1b r0, r3, ne, abort=21f
- str1b r0, r4, cs, abort=21f
- str1b r0, ip, cs, abort=21f
-
- exit r4, pc
-
-9: rsb ip, ip, #4
- cmp ip, #2
- ldr1b r1, r3, gt, abort=21f
- ldr1b r1, r4, ge, abort=21f
- ldr1b r1, lr, abort=21f
- str1b r0, r3, gt, abort=21f
- str1b r0, r4, ge, abort=21f
- subs r2, r2, ip
- str1b r0, lr, abort=21f
- blt 8b
- ands ip, r1, #3
- beq 1b
-
-10: bic r1, r1, #3
- cmp ip, #2
- ldr1w r1, lr, abort=21f
- beq 17f
- bgt 18f
-
-
- .macro forward_copy_shift pull push
-
- subs r2, r2, #28
- blt 14f
-
- CALGN( ands ip, r1, #31 )
- CALGN( rsb ip, ip, #32 )
- CALGN( sbcnes r4, ip, r2 ) @ C is always set here
- CALGN( subcc r2, r2, ip )
- CALGN( bcc 15f )
-
-11: stmfd sp!, {r5 - r9}
-
- PLD( pld [r1, #0] )
- PLD( subs r2, r2, #96 )
- PLD( pld [r1, #28] )
- PLD( blt 13f )
- PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
-
-12: PLD( pld [r1, #124] )
-13: ldr4w r1, r4, r5, r6, r7, abort=19f
- mov r3, lr, pull #\pull
- subs r2, r2, #32
- ldr4w r1, r8, r9, ip, lr, abort=19f
- orr r3, r3, r4, push #\push
- mov r4, r4, pull #\pull
- orr r4, r4, r5, push #\push
- mov r5, r5, pull #\pull
- orr r5, r5, r6, push #\push
- mov r6, r6, pull #\pull
- orr r6, r6, r7, push #\push
- mov r7, r7, pull #\pull
- orr r7, r7, r8, push #\push
- mov r8, r8, pull #\pull
- orr r8, r8, r9, push #\push
- mov r9, r9, pull #\pull
- orr r9, r9, ip, push #\push
- mov ip, ip, pull #\pull
- orr ip, ip, lr, push #\push
- str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
- bge 12b
- PLD( cmn r2, #96 )
- PLD( bge 13b )
-
- ldmfd sp!, {r5 - r9}
-
-14: ands ip, r2, #28
- beq 16f
-
-15: mov r3, lr, pull #\pull
- ldr1w r1, lr, abort=21f
- subs ip, ip, #4
- orr r3, r3, lr, push #\push
- str1w r0, r3, abort=21f
- bgt 15b
- CALGN( cmp r2, #0 )
- CALGN( bge 11b )
-
-16: sub r1, r1, #(\push / 8)
- b 8b
-
- .endm
-
-
- forward_copy_shift pull=8 push=24
-
-17: forward_copy_shift pull=16 push=16
-
-18: forward_copy_shift pull=24 push=8
-
-
-/*
- * Abort preamble and completion macros.
- * If a fixup handler is required then those macros must surround it.
- * It is assumed that the fixup code will handle the private part of
- * the exit macro.
- */
-
- .macro copy_abort_preamble
-19: ldmfd sp!, {r5 - r9}
- b 21f
-20: ldmfd sp!, {r5 - r8}
-21:
- .endm
-
- .macro copy_abort_end
- ldmfd sp!, {r4, pc}
- .endm
-
diff --git a/src/target/firmware/lib/ctype.c b/src/target/firmware/lib/ctype.c
deleted file mode 100644
index f3732140..00000000
--- a/src/target/firmware/lib/ctype.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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 */
-
diff --git a/src/target/firmware/lib/lib1funcs.S b/src/target/firmware/lib/lib1funcs.S
deleted file mode 100644
index b02a85eb..00000000
--- a/src/target/firmware/lib/lib1funcs.S
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * 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 <asm/linkage.h>
-#include <asm/assembler.h>
-
-
-.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
-
-
-ENTRY(__udivsi3)
-ENTRY(__aeabi_uidiv)
-
- 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
-
-
-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
-
-
-ENTRY(__divsi3)
-ENTRY(__aeabi_idiv)
-
- 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
-
-
-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
-
-ENTRY(__aeabi_uidivmod)
-
- stmfd sp!, {r0, r1, ip, lr}
- bl __aeabi_uidiv
- ldmfd sp!, {r1, r2, ip, lr}
- mul r3, r0, r2
- sub r1, r1, r3
- mov pc, lr
-
-ENTRY(__aeabi_idivmod)
-
- stmfd sp!, {r0, r1, ip, lr}
- bl __aeabi_idiv
- ldmfd sp!, {r1, r2, ip, lr}
- mul r3, r0, r2
- sub r1, r1, r3
- mov pc, lr
-
-Ldiv0:
-
- str lr, [sp, #-8]!
- bl __div0
- mov r0, #0 @ About as wrong as it could be.
- ldr pc, [sp], #8
-
-ENTRY(__div0)
- mov pc, lr
diff --git a/src/target/firmware/lib/memcpy.S b/src/target/firmware/lib/memcpy.S
deleted file mode 100644
index 2bbd5692..00000000
--- a/src/target/firmware/lib/memcpy.S
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * linux/arch/arm/lib/memcpy.S
- *
- * Author: Nicolas Pitre
- * Created: Sep 28, 2005
- * Copyright: MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <asm/linkage.h>
-#include <asm/assembler.h>
-
- .macro ldr1w ptr reg abort
- ldr \reg, [\ptr], #4
- .endm
-
- .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
- ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
- .endm
-
- .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
- ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
- .endm
-
- .macro ldr1b ptr reg cond=al abort
- ldr\cond\()b \reg, [\ptr], #1
- .endm
-
- .macro str1w ptr reg abort
- str \reg, [\ptr], #4
- .endm
-
- .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
- stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
- .endm
-
- .macro str1b ptr reg cond=al abort
- str\cond\()b \reg, [\ptr], #1
- .endm
-
- .macro enter reg1 reg2
- stmdb sp!, {r0, \reg1, \reg2}
- .endm
-
- .macro exit reg1 reg2
- ldmfd sp!, {r0, \reg1, \reg2}
- .endm
-
- .text
-
-/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
-
-ENTRY(memcpy)
-
-#include "copy_template.S"
-
diff --git a/src/target/firmware/lib/memset.S b/src/target/firmware/lib/memset.S
deleted file mode 100644
index 04e254a8..00000000
--- a/src/target/firmware/lib/memset.S
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * linux/arch/arm/lib/memset.S
- *
- * Copyright (C) 1995-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * ASM optimised string functions
- */
-#include <asm/linkage.h>
-#include <asm/assembler.h>
-
- .text
- .align 5
- .word 0
-
-1: subs r2, r2, #4 @ 1 do we have enough
- blt 5f @ 1 bytes to align with?
- cmp r3, #2 @ 1
- strltb r1, [r0], #1 @ 1
- strleb r1, [r0], #1 @ 1
- strb r1, [r0], #1 @ 1
- add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
-/*
- * The pointer is now aligned and the length is adjusted. Try doing the
- * memzero again.
- */
-
-ENTRY(memset)
- ands r3, r0, #3 @ 1 unaligned?
- bne 1b @ 1
-/*
- * we know that the pointer in r0 is aligned to a word boundary.
- */
- orr r1, r1, r1, lsl #8
- orr r1, r1, r1, lsl #16
- mov r3, r1
- cmp r2, #16
- blt 4f
-/*
- * We need an extra register for this loop - save the return address and
- * use the LR
- */
- str lr, [sp, #-4]!
- mov ip, r1
- mov lr, r1
-
-2: subs r2, r2, #64
- stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
- stmgeia r0!, {r1, r3, ip, lr}
- stmgeia r0!, {r1, r3, ip, lr}
- stmgeia r0!, {r1, r3, ip, lr}
- bgt 2b
- LOADREGS(eqfd, sp!, {pc}) @ Now <64 bytes to go.
-/*
- * No need to correct the count; we're only testing bits from now on
- */
- tst r2, #32
- stmneia r0!, {r1, r3, ip, lr}
- stmneia r0!, {r1, r3, ip, lr}
- tst r2, #16
- stmneia r0!, {r1, r3, ip, lr}
- ldr lr, [sp], #4
-
-4: tst r2, #8
- stmneia r0!, {r1, r3}
- tst r2, #4
- strne r1, [r0], #4
-/*
- * When we get here, we've got less than 4 bytes to zero. We
- * may have an unaligned pointer as well.
- */
-5: tst r2, #2
- strneb r1, [r0], #1
- strneb r1, [r0], #1
- tst r2, #1
- strneb r1, [r0], #1
- RETINSTR(mov,pc,lr)
diff --git a/src/target/firmware/lib/printf.c b/src/target/firmware/lib/printf.c
deleted file mode 100644
index a4fc6876..00000000
--- a/src/target/firmware/lib/printf.c
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#include <stdio.h>
-#include <stdarg.h>
-
-static char printf_buffer[1024];
-
-int printf(const char *fmt, ...)
-{
- va_list args;
- int r;
-
- va_start(args, fmt);
- r = vsnprintf(printf_buffer, sizeof(printf_buffer), fmt, args);
- va_end(args);
-
- puts(printf_buffer);
-
- return r;
-}
diff --git a/src/target/firmware/lib/string.c b/src/target/firmware/lib/string.c
deleted file mode 100644
index 97036528..00000000
--- a/src/target/firmware/lib/string.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.
- *
- * * Sat Feb 09 2002, Jason Thomas <jason@topic.com.au>,
- * Matthew Hawkins <matt@mh.dropbear.id.au>
- * - Kissed strtok() goodbye
- */
-
-#include <sys/types.h>
-#include <string.h>
-#include <ctype.h>
-
-
-#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
-
-size_t strlen(const char *s)
-{
- const char *sc;
-
- for (sc = s; *sc != '\0'; ++sc)
- /* nothing */;
- return sc - s;
-}
diff --git a/src/target/firmware/lib/system.c b/src/target/firmware/lib/system.c
new file mode 100644
index 00000000..48ef5f1e
--- /dev/null
+++ b/src/target/firmware/lib/system.c
@@ -0,0 +1,42 @@
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <comm/sercomm_cons.h>
+
+int errno;
+
+int ioctl(int fd, long int request, ...) {
+ return 0;
+}
+
+ssize_t __libc_write(int fd, const void *buf, size_t count) {
+ char c;
+ int i;
+
+ switch(fd) {
+ default:
+ case 0:
+ errno = EBADF;
+ return -1;
+ case 1:
+ case 2:
+ return sercomm_write(buf, count);
+ }
+}
+
+ssize_t write(int fd, const void *buf, size_t count) {
+ return __libc_write(fd, buf, count);
+}
+
+off_t lseek(int fd, off_t offset, int whence) {
+ return offset;
+}
+
+void _exit(int status) {
+ puts("Program exit\n");
+ while(1) { }
+}
diff --git a/src/target/firmware/lib/vsprintf.c b/src/target/firmware/lib/vsprintf.c
deleted file mode 100644
index 80e8c1ad..00000000
--- a/src/target/firmware/lib/vsprintf.c
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
- * linux/lib/vsprintf.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
-/*
- * Wirzenius wrote this portably, Torvalds fucked it up :-)
- */
-
-/*
- * Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
- * - changed to provide snprintf and vsnprintf functions
- * So Feb 1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
- * - scnprintf and vscnprintf
- */
-
-#include <stdio.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <asm/div64.h>
-
-/**
- * strtoul - convert a string to an unsigned long
- * @cp: The start of the string
- * @endp: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-unsigned long strtoul(const char *cp,char **endp,unsigned int base)
-{
- unsigned long result = 0,value;
-
- if (!base) {
- base = 10;
- if (*cp == '0') {
- base = 8;
- cp++;
- if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
- cp++;
- base = 16;
- }
- }
- } else if (base == 16) {
- if (cp[0] == '0' && toupper(cp[1]) == 'X')
- cp += 2;
- }
- while (isxdigit(*cp) &&
- (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
- result = result*base + value;
- cp++;
- }
- if (endp)
- *endp = (char *)cp;
- return result;
-}
-
-
-/**
- * strtol - convert a string to a signed long
- * @cp: The start of the string
- * @endp: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-long strtol(const char *cp,char **endp,unsigned int base)
-{
- if(*cp=='-')
- return -strtoul(cp+1,endp,base);
- return strtoul(cp,endp,base);
-}
-
-
-/**
- * strtoull - convert a string to an unsigned long long
- * @cp: The start of the string
- * @endp: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-unsigned long long strtoull(const char *cp,char **endp,unsigned int base)
-{
- unsigned long long result = 0,value;
-
- if (!base) {
- base = 10;
- if (*cp == '0') {
- base = 8;
- cp++;
- if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
- cp++;
- base = 16;
- }
- }
- } else if (base == 16) {
- if (cp[0] == '0' && toupper(cp[1]) == 'X')
- cp += 2;
- }
- while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
- ? toupper(*cp) : *cp)-'A'+10) < base) {
- result = result*base + value;
- cp++;
- }
- if (endp)
- *endp = (char *)cp;
- return result;
-}
-
-
-/**
- * strtoll - convert a string to a signed long long
- * @cp: The start of the string
- * @endp: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-long long strtoll(const char *cp,char **endp,unsigned int base)
-{
- if(*cp=='-')
- return -strtoull(cp+1,endp,base);
- return strtoull(cp,endp,base);
-}
-
-static int skip_atoi(const char **s)
-{
- int i=0;
-
- while (isdigit(**s))
- i = i*10 + *((*s)++) - '0';
- return i;
-}
-
-#define ZEROPAD 1 /* pad with zero */
-#define SIGN 2 /* unsigned/signed long */
-#define PLUS 4 /* show plus */
-#define SPACE 8 /* space if plus */
-#define LEFT 16 /* left justified */
-#define SPECIAL 32 /* 0x */
-#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
-
-static char * number(char * buf, char * end, unsigned long long num, int base, int size, int precision, int type)
-{
- char c,sign,tmp[66];
- const char *digits;
- static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
- static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- int i;
-
- digits = (type & LARGE) ? large_digits : small_digits;
- if (type & LEFT)
- type &= ~ZEROPAD;
- if (base < 2 || base > 36)
- return NULL;
- c = (type & ZEROPAD) ? '0' : ' ';
- sign = 0;
- if (type & SIGN) {
- if ((signed long long) num < 0) {
- sign = '-';
- num = - (signed long long) num;
- size--;
- } else if (type & PLUS) {
- sign = '+';
- size--;
- } else if (type & SPACE) {
- sign = ' ';
- size--;
- }
- }
- if (type & SPECIAL) {
- if (base == 16)
- size -= 2;
- else if (base == 8)
- size--;
- }
- i = 0;
- if (num == 0)
- tmp[i++]='0';
- else while (num != 0)
- tmp[i++] = digits[do_div(num,base)];
- if (i > precision)
- precision = i;
- size -= precision;
- if (!(type&(ZEROPAD+LEFT))) {
- while(size-->0) {
- if (buf <= end)
- *buf = ' ';
- ++buf;
- }
- }
- if (sign) {
- if (buf <= end)
- *buf = sign;
- ++buf;
- }
- if (type & SPECIAL) {
- if (base==8) {
- if (buf <= end)
- *buf = '0';
- ++buf;
- } else if (base==16) {
- if (buf <= end)
- *buf = '0';
- ++buf;
- if (buf <= end)
- *buf = digits[33];
- ++buf;
- }
- }
- if (!(type & LEFT)) {
- while (size-- > 0) {
- if (buf <= end)
- *buf = c;
- ++buf;
- }
- }
- while (i < precision--) {
- if (buf <= end)
- *buf = '0';
- ++buf;
- }
- while (i-- > 0) {
- if (buf <= end)
- *buf = tmp[i];
- ++buf;
- }
- while (size-- > 0) {
- if (buf <= end)
- *buf = ' ';
- ++buf;
- }
- return buf;
-}
-
-/**
- * vsnprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @args: Arguments for the format string
- *
- * The return value is the number of characters which would
- * be generated for the given input, excluding the trailing
- * '\0', as per ISO C99. If you want to have the exact
- * number of characters written into @buf as return value
- * (not including the trailing '\0'), use vscnprintf. If the
- * return is greater than or equal to @size, the resulting
- * string is truncated.
- *
- * Call this function if you are already dealing with a va_list.
- * You probably want snprintf instead.
- */
-int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
-{
- int len;
- unsigned long long num;
- int i, base;
- char *str, *end, c;
- const char *s;
-
- int flags; /* flags to number() */
-
- int field_width; /* width of output field */
- int precision; /* min. # of digits for integers; max
- number of chars for from string */
- int qualifier; /* 'h', 'l', or 'L' for integer fields */
- /* 'z' support added 23/7/1999 S.H. */
- /* 'z' changed to 'Z' --davidm 1/25/99 */
- /* 't' added for ptrdiff_t */
-
- /* Reject out-of-range values early */
- if ((int) size < 0) {
- return 0;
- }
-
- str = buf;
- end = buf + size - 1;
-
- if (end < buf - 1) {
- end = ((void *) -1);
- size = end - buf + 1;
- }
-
- for (; *fmt ; ++fmt) {
- if (*fmt != '%') {
- if (str <= end)
- *str = *fmt;
- ++str;
- continue;
- }
-
- /* process flags */
- flags = 0;
- repeat:
- ++fmt; /* this also skips first '%' */
- switch (*fmt) {
- case '-': flags |= LEFT; goto repeat;
- case '+': flags |= PLUS; goto repeat;
- case ' ': flags |= SPACE; goto repeat;
- case '#': flags |= SPECIAL; goto repeat;
- case '0': flags |= ZEROPAD; goto repeat;
- }
-
- /* get field width */
- field_width = -1;
- if (isdigit(*fmt))
- field_width = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- field_width = va_arg(args, int);
- if (field_width < 0) {
- field_width = -field_width;
- flags |= LEFT;
- }
- }
-
- /* get the precision */
- precision = -1;
- if (*fmt == '.') {
- ++fmt;
- if (isdigit(*fmt))
- precision = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- precision = va_arg(args, int);
- }
- if (precision < 0)
- precision = 0;
- }
-
- /* get the conversion qualifier */
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
- *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
- qualifier = *fmt;
- ++fmt;
- if (qualifier == 'l' && *fmt == 'l') {
- qualifier = 'L';
- ++fmt;
- }
- }
-
- /* default base */
- base = 10;
-
- switch (*fmt) {
- case 'c':
- if (!(flags & LEFT)) {
- while (--field_width > 0) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- }
- c = (unsigned char) va_arg(args, int);
- if (str <= end)
- *str = c;
- ++str;
- while (--field_width > 0) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- continue;
-
- case 's':
- s = va_arg(args, char *);
-
- len = strnlen(s, precision);
-
- if (!(flags & LEFT)) {
- while (len < field_width--) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- }
- for (i = 0; i < len; ++i) {
- if (str <= end)
- *str = *s;
- ++str; ++s;
- }
- while (len < field_width--) {
- if (str <= end)
- *str = ' ';
- ++str;
- }
- continue;
-
- case 'p':
- if (field_width == -1) {
- field_width = 2*sizeof(void *);
- flags |= ZEROPAD;
- }
- str = number(str, end,
- (unsigned long) va_arg(args, void *),
- 16, field_width, precision, flags);
- continue;
-
-
- case 'n':
- /* FIXME:
- * What does C99 say about the overflow case here? */
- if (qualifier == 'l') {
- long * ip = va_arg(args, long *);
- *ip = (str - buf);
- } else if (qualifier == 'Z' || qualifier == 'z') {
- size_t * ip = va_arg(args, size_t *);
- *ip = (str - buf);
- } else {
- int * ip = va_arg(args, int *);
- *ip = (str - buf);
- }
- continue;
-
- case '%':
- if (str <= end)
- *str = '%';
- ++str;
- continue;
-
- /* integer number formats - set up the flags and "break" */
- case 'o':
- base = 8;
- break;
-
- case 'X':
- flags |= LARGE;
- case 'x':
- base = 16;
- break;
-
- case 'd':
- case 'i':
- flags |= SIGN;
- case 'u':
- break;
-
- default:
- if (str <= end)
- *str = '%';
- ++str;
- if (*fmt) {
- if (str <= end)
- *str = *fmt;
- ++str;
- } else {
- --fmt;
- }
- continue;
- }
- if (qualifier == 'L')
- num = va_arg(args, long long);
- else if (qualifier == 'l') {
- num = va_arg(args, unsigned long);
- if (flags & SIGN)
- num = (signed long) num;
- } else if (qualifier == 'Z' || qualifier == 'z') {
- num = va_arg(args, size_t);
- } else if (qualifier == 't') {
- num = va_arg(args, long);
- } else if (qualifier == 'h') {
- num = (unsigned short) va_arg(args, int);
- if (flags & SIGN)
- num = (signed short) num;
- } else {
- num = va_arg(args, unsigned int);
- if (flags & SIGN)
- num = (signed int) num;
- }
- str = number(str, end, num, base,
- field_width, precision, flags);
- }
- if (str <= end)
- *str = '\0';
- else if (size > 0)
- /* don't write out a null byte if the buf size is zero */
- *end = '\0';
- /* the trailing null byte doesn't count towards the total
- * ++str;
- */
- return str-buf;
-}
-
-
-/**
- * vscnprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @args: Arguments for the format string
- *
- * The return value is the number of characters which have been written into
- * the @buf not including the trailing '\0'. If @size is <= 0 the function
- * returns 0.
- *
- * Call this function if you are already dealing with a va_list.
- * You probably want scnprintf instead.
- */
-int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
-{
- unsigned int i;
-
- i=vsnprintf(buf,size,fmt,args);
- return (i >= size) ? (size - 1) : i;
-}
-
-
-/**
- * snprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @...: Arguments for the format string
- *
- * The return value is the number of characters which would be
- * generated for the given input, excluding the trailing null,
- * as per ISO C99. If the return is greater than or equal to
- * @size, the resulting string is truncated.
- */
-int snprintf(char * buf, size_t size, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i=vsnprintf(buf,size,fmt,args);
- va_end(args);
- return i;
-}
-
-
-/**
- * scnprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @...: Arguments for the format string
- *
- * The return value is the number of characters written into @buf not including
- * the trailing '\0'. If @size is <= 0 the function returns 0. If the return is
- * greater than or equal to @size, the resulting string is truncated.
- */
-
-int scnprintf(char * buf, size_t size, const char *fmt, ...)
-{
- va_list args;
- unsigned int i;
-
- va_start(args, fmt);
- i = vsnprintf(buf, size, fmt, args);
- va_end(args);
- return (i >= size) ? (size - 1) : i;
-}
-
-/**
- * vsprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @fmt: The format string to use
- * @args: Arguments for the format string
- *
- * The function returns the number of characters written
- * into @buf. Use vsnprintf or vscnprintf in order to avoid
- * buffer overflows.
- *
- * Call this function if you are already dealing with a va_list.
- * You probably want sprintf instead.
- */
-int vsprintf(char *buf, const char *fmt, va_list args)
-{
- return vsnprintf(buf, INT_MAX, fmt, args);
-}
-
-
-/**
- * sprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @fmt: The format string to use
- * @...: Arguments for the format string
- *
- * The function returns the number of characters written
- * into @buf. Use snprintf or scnprintf in order to avoid
- * buffer overflows.
- */
-int sprintf(char * buf, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i=vsnprintf(buf, INT_MAX, fmt, args);
- va_end(args);
- return i;
-}
-
-
-/**
- * vsscanf - Unformat a buffer into a list of arguments
- * @buf: input buffer
- * @fmt: format of buffer
- * @args: arguments
- */
-int vsscanf(const char * buf, const char * fmt, va_list args)
-{
- const char *str = buf;
- char *next;
- char digit;
- int num = 0;
- int qualifier;
- int base;
- int field_width;
- int is_sign = 0;
-
- while(*fmt && *str) {
- /* skip any white space in format */
- /* white space in format matchs any amount of
- * white space, including none, in the input.
- */
- if (isspace(*fmt)) {
- while (isspace(*fmt))
- ++fmt;
- while (isspace(*str))
- ++str;
- }
-
- /* anything that is not a conversion must match exactly */
- if (*fmt != '%' && *fmt) {
- if (*fmt++ != *str++)
- break;
- continue;
- }
-
- if (!*fmt)
- break;
- ++fmt;
-
- /* skip this conversion.
- * advance both strings to next white space
- */
- if (*fmt == '*') {
- while (!isspace(*fmt) && *fmt)
- fmt++;
- while (!isspace(*str) && *str)
- str++;
- continue;
- }
-
- /* get field width */
- field_width = -1;
- if (isdigit(*fmt))
- field_width = skip_atoi(&fmt);
-
- /* get conversion qualifier */
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
- *fmt == 'Z' || *fmt == 'z') {
- qualifier = *fmt++;
- if (qualifier == *fmt) {
- if (qualifier == 'h') {
- qualifier = 'H';
- fmt++;
- } else if (qualifier == 'l') {
- qualifier = 'L';
- fmt++;
- }
- }
- }
- base = 10;
- is_sign = 0;
-
- if (!*fmt || !*str)
- break;
-
- switch(*fmt++) {
- case 'c':
- {
- char *s = (char *) va_arg(args,char*);
- if (field_width == -1)
- field_width = 1;
- do {
- *s++ = *str++;
- } while (--field_width > 0 && *str);
- num++;
- }
- continue;
- case 's':
- {
- char *s = (char *) va_arg(args, char *);
- if(field_width == -1)
- field_width = INT_MAX;
- /* first, skip leading white space in buffer */
- while (isspace(*str))
- str++;
-
- /* now copy until next white space */
- while (*str && !isspace(*str) && field_width--) {
- *s++ = *str++;
- }
- *s = '\0';
- num++;
- }
- continue;
- case 'n':
- /* return number of characters read so far */
- {
- int *i = (int *)va_arg(args,int*);
- *i = str - buf;
- }
- continue;
- case 'o':
- base = 8;
- break;
- case 'x':
- case 'X':
- base = 16;
- break;
- case 'i':
- base = 0;
- case 'd':
- is_sign = 1;
- case 'u':
- break;
- case '%':
- /* looking for '%' in str */
- if (*str++ != '%')
- return num;
- continue;
- default:
- /* invalid format; stop here */
- return num;
- }
-
- /* have some sort of integer conversion.
- * first, skip white space in buffer.
- */
- while (isspace(*str))
- str++;
-
- digit = *str;
- if (is_sign && digit == '-')
- digit = *(str + 1);
-
- if (!digit
- || (base == 16 && !isxdigit(digit))
- || (base == 10 && !isdigit(digit))
- || (base == 8 && (!isdigit(digit) || digit > '7'))
- || (base == 0 && !isdigit(digit)))
- break;
-
- switch(qualifier) {
- case 'H': /* that's 'hh' in format */
- if (is_sign) {
- signed char *s = (signed char *) va_arg(args,signed char *);
- *s = (signed char) strtol(str,&next,base);
- } else {
- unsigned char *s = (unsigned char *) va_arg(args, unsigned char *);
- *s = (unsigned char) strtoul(str, &next, base);
- }
- break;
- case 'h':
- if (is_sign) {
- short *s = (short *) va_arg(args,short *);
- *s = (short) strtol(str,&next,base);
- } else {
- unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
- *s = (unsigned short) strtoul(str, &next, base);
- }
- break;
- case 'l':
- if (is_sign) {
- long *l = (long *) va_arg(args,long *);
- *l = strtol(str,&next,base);
- } else {
- unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
- *l = strtoul(str,&next,base);
- }
- break;
- case 'L':
- if (is_sign) {
- long long *l = (long long*) va_arg(args,long long *);
- *l = strtoll(str,&next,base);
- } else {
- unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
- *l = strtoull(str,&next,base);
- }
- break;
- case 'Z':
- case 'z':
- {
- size_t *s = (size_t*) va_arg(args,size_t*);
- *s = (size_t) strtoul(str,&next,base);
- }
- break;
- default:
- if (is_sign) {
- int *i = (int *) va_arg(args, int*);
- *i = (int) strtol(str,&next,base);
- } else {
- unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
- *i = (unsigned int) strtoul(str,&next,base);
- }
- break;
- }
- num++;
-
- if (!next)
- break;
- str = next;
- }
- return num;
-}
-
-
-/**
- * sscanf - Unformat a buffer into a list of arguments
- * @buf: input buffer
- * @fmt: formatting of buffer
- * @...: resulting arguments
- */
-int sscanf(const char * buf, const char * fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args,fmt);
- i = vsscanf(buf,fmt,args);
- va_end(args);
- return i;
-}
-
-/* generic puts() implementation independent of who provides putchar() */
-int puts(const char *s)
-{
-#ifdef ARCH_HAS_CONSOLE
- return _puts(s);
-#else
- while (1) {
- char c = *s++;
- if (c == 0)
- return;
- putchar(c);
- }
- return 0;
-#endif
-}