diff options
author | Yang Zhang <yang.z.zhang@intel.com> | 2015-08-28 09:58:54 +0800 |
---|---|---|
committer | Yang Zhang <yang.z.zhang@intel.com> | 2015-09-01 12:44:00 +0800 |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/SLOF/lib/libc/stdlib | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/SLOF/lib/libc/stdlib')
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/Makefile.inc | 22 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/atoi.c | 18 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/atol.c | 18 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/error.c | 15 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/free.c | 26 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/malloc.c | 157 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/malloc_defs.h | 16 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/memalign.c | 26 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/rand.c | 24 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/realloc.c | 40 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/strtol.c | 115 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libc/stdlib/strtoul.c | 105 |
12 files changed, 582 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/lib/libc/stdlib/Makefile.inc b/qemu/roms/SLOF/lib/libc/stdlib/Makefile.inc new file mode 100644 index 000000000..702f6d7cf --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/Makefile.inc @@ -0,0 +1,22 @@ +# ***************************************************************************** +# * Copyright (c) 2004, 2008 IBM Corporation +# * All rights reserved. +# * This program and the accompanying materials +# * are made available under the terms of the BSD License +# * which accompanies this distribution, and is available at +# * http://www.opensource.org/licenses/bsd-license.php +# * +# * Contributors: +# * IBM Corporation - initial implementation +# ****************************************************************************/ + + +STDLIB_SRC_C = error.c atoi.c atol.c strtoul.c strtol.c rand.c \ + malloc.c memalign.c realloc.c free.c + +STDLIB_SRC_ASM = +STDLIB_SRCS = $(STDLIB_SRC_C:%=$(STDLIBCMNDIR)/%) $(STDLIB_SRC_ASM:%=$(STDLIBCMNDIR)/%) +STDLIB_OBJS = $(STDLIB_SRC_C:%.c=%.o) $(STDLIB_SRC_ASM:%.S=%.o) + +%.o : $(STDLIBCMNDIR)/%.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ diff --git a/qemu/roms/SLOF/lib/libc/stdlib/atoi.c b/qemu/roms/SLOF/lib/libc/stdlib/atoi.c new file mode 100644 index 000000000..d2fb33b88 --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/atoi.c @@ -0,0 +1,18 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdlib.h> + +int atoi(const char *str) +{ + return strtol(str, NULL, 0); +} diff --git a/qemu/roms/SLOF/lib/libc/stdlib/atol.c b/qemu/roms/SLOF/lib/libc/stdlib/atol.c new file mode 100644 index 000000000..a6aa47ba5 --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/atol.c @@ -0,0 +1,18 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdlib.h> + +long atol(const char *str) +{ + return strtol(str, NULL, 0); +} diff --git a/qemu/roms/SLOF/lib/libc/stdlib/error.c b/qemu/roms/SLOF/lib/libc/stdlib/error.c new file mode 100644 index 000000000..81020ca55 --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/error.c @@ -0,0 +1,15 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +int errno; + diff --git a/qemu/roms/SLOF/lib/libc/stdlib/free.c b/qemu/roms/SLOF/lib/libc/stdlib/free.c new file mode 100644 index 000000000..900545099 --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/free.c @@ -0,0 +1,26 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +#include "stdlib.h" +#include "malloc_defs.h" + +void +free(void *ptr) +{ + struct chunk *header; + + header = (struct chunk *) ptr; + header--; + header->inuse = 0; + +} diff --git a/qemu/roms/SLOF/lib/libc/stdlib/malloc.c b/qemu/roms/SLOF/lib/libc/stdlib/malloc.c new file mode 100644 index 000000000..b2a3138eb --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/malloc.c @@ -0,0 +1,157 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +#include "stddef.h" +#include "stdlib.h" +#include "unistd.h" +#include "malloc_defs.h" + + +static int clean(void); + + +/* act points to the end of the initialized heap and the start of uninitialized heap */ +static char *act; + +/* Pointers to start and end of heap: */ +static char *heap_start, *heap_end; + + +/* + * Standard malloc function + */ +void * +malloc(size_t size) +{ + char *header; + void *data; + size_t blksize; /* size of memory block including the chunk */ + + blksize = size + sizeof(struct chunk); + + /* has malloc been called for the first time? */ + if (act == 0) { + size_t initsize; + /* add some space so we have a good initial playground */ + initsize = (blksize + 0x1000) & ~0x0fff; + /* get initial memory region with sbrk() */ + heap_start = sbrk(initsize); + if (heap_start == (void*)-1) + return NULL; + heap_end = heap_start + initsize; + act = heap_start; + } + + header = act; + data = act + sizeof(struct chunk); + + /* Check if there is space left in the uninitialized part of the heap */ + if (act + blksize > heap_end) { + //search at begin of heap + header = heap_start; + + while ((((struct chunk *) header)->inuse != 0 + || ((struct chunk *) header)->length < size) + && header < act) { + header = header + sizeof(struct chunk) + + ((struct chunk *) header)->length; + } + + // check if heap is full + if (header >= act) { + if (clean()) { + // merging of free blocks succeeded, so try again + return malloc(size); + } else if (sbrk(blksize) == heap_end) { + // succeeded to get more memory, so try again + heap_end += blksize; + return malloc(size); + } else { + // No more memory available + return 0; + } + } + + // Check if we need to split this memory block into two + if (((struct chunk *) header)->length > blksize) { + //available memory is too big + int alt; + + alt = ((struct chunk *) header)->length; + ((struct chunk *) header)->inuse = 1; + ((struct chunk *) header)->length = size; + data = header + sizeof(struct chunk); + + //mark the rest of the heap + header = data + size; + ((struct chunk *) header)->inuse = 0; + ((struct chunk *) header)->length = + alt - blksize; + } else { + //new memory matched exactly in available memory + ((struct chunk *) header)->inuse = 1; + data = header + sizeof(struct chunk); + } + + } else { + + ((struct chunk *) header)->inuse = 1; + ((struct chunk *) header)->length = size; + + act += blksize; + } + + return data; +} + + +/* + * Merge free memory blocks in initialized heap if possible + */ +static int +clean(void) +{ + char *header; + char *firstfree = 0; + char check = 0; + + header = heap_start; + //if (act == 0) // This should never happen + // act = heap_end; + + while (header < act) { + + if (((struct chunk *) header)->inuse == 0) { + if (firstfree == 0) { + /* First free block in a row, only save address */ + firstfree = header; + + } else { + /* more than one free block in a row, merge them! */ + ((struct chunk *) firstfree)->length += + ((struct chunk *) header)->length + + sizeof(struct chunk); + check = 1; + } + } else { + firstfree = 0; + + } + + header = header + sizeof(struct chunk) + + ((struct chunk *) header)->length; + + } + + return check; +} diff --git a/qemu/roms/SLOF/lib/libc/stdlib/malloc_defs.h b/qemu/roms/SLOF/lib/libc/stdlib/malloc_defs.h new file mode 100644 index 000000000..19330267e --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/malloc_defs.h @@ -0,0 +1,16 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +struct chunk { + unsigned inuse : 4; + unsigned length : 28; +} __attribute__((packed)); diff --git a/qemu/roms/SLOF/lib/libc/stdlib/memalign.c b/qemu/roms/SLOF/lib/libc/stdlib/memalign.c new file mode 100644 index 000000000..3b678aaf5 --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/memalign.c @@ -0,0 +1,26 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +#include "stdlib.h" + + +void * +memalign(size_t blocksize, size_t bytes) +{ + void *x; + + x = malloc(bytes + blocksize); + x = (void *) (((unsigned long) x + blocksize - 1) & ~(blocksize - 1)); + + return (void *) x; +} diff --git a/qemu/roms/SLOF/lib/libc/stdlib/rand.c b/qemu/roms/SLOF/lib/libc/stdlib/rand.c new file mode 100644 index 000000000..87e3efd29 --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/rand.c @@ -0,0 +1,24 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdlib.h> + + +static unsigned long _rand = 1; + +int +rand(void) +{ + _rand = _rand * 25364735 + 34563; + + return ((unsigned int) (_rand << 16) & RAND_MAX); +} diff --git a/qemu/roms/SLOF/lib/libc/stdlib/realloc.c b/qemu/roms/SLOF/lib/libc/stdlib/realloc.c new file mode 100644 index 000000000..652e90077 --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/realloc.c @@ -0,0 +1,40 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + + +#include "stdlib.h" +#include "string.h" +#include "malloc_defs.h" + +void * +realloc(void *ptr, size_t size) +{ + struct chunk *header; + char *newptr, *start; + + header = (struct chunk *) ptr; + header--; + + if (size <= header->length) + return ptr; + + newptr = (char *) malloc(size); + if (newptr == NULL) + return 0; + + start = newptr; + memcpy((void *) newptr, (const void *) ptr, header->length); + + header->inuse = 0; + + return start; +} diff --git a/qemu/roms/SLOF/lib/libc/stdlib/strtol.c b/qemu/roms/SLOF/lib/libc/stdlib/strtol.c new file mode 100644 index 000000000..474597a23 --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/strtol.c @@ -0,0 +1,115 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdlib.h> + +long int strtol(const char *S, char **PTR,int BASE) +{ + long rval = 0; + short int negative = 0; + short int digit; + // *PTR is S, unless PTR is NULL, in which case i override it with my own ptr + char* ptr; + if (PTR == 0) + { + //override + PTR = &ptr; + } + // i use PTR to advance through the string + *PTR = (char *) S; + //check if BASE is ok + if ((BASE < 0) || BASE > 36) + { + return 0; + } + // ignore white space at beginning of S + while ((**PTR == ' ') + || (**PTR == '\t') + || (**PTR == '\n') + || (**PTR == '\r') + ) + { + (*PTR)++; + } + // check if S starts with "-" in which case the return value is negative + if (**PTR == '-') + { + negative = 1; + (*PTR)++; + } + // if BASE is 0... determine the base from the first chars... + if (BASE == 0) + { + // if S starts with "0x", BASE = 16, else 10 + if ((**PTR == '0') && (*((*PTR)+1) == 'x')) + { + BASE = 16; + (*PTR)++; + (*PTR)++; + } + else + { + BASE = 10; + } + } + if (BASE == 16) + { + // S may start with "0x" + if ((**PTR == '0') && (*((*PTR)+1) == 'x')) + { + (*PTR)++; + (*PTR)++; + } + } + //until end of string + while (**PTR) + { + if (((**PTR) >= '0') && ((**PTR) <= '9')) + { + //digit (0..9) + digit = **PTR - '0'; + } + else if (((**PTR) >= 'a') && ((**PTR) <='z')) + { + //alphanumeric digit lowercase(a (10) .. z (35) ) + digit = (**PTR - 'a') + 10; + } + else if (((**PTR) >= 'A') && ((**PTR) <='Z')) + { + //alphanumeric digit uppercase(a (10) .. z (35) ) + digit = (**PTR - 'A') + 10; + } + else + { + //end of parseable number reached... + break; + } + if (digit < BASE) + { + rval = (rval * BASE) + digit; + } + else + { + //digit found, but its too big for current base + //end of parseable number reached... + break; + } + //next... + (*PTR)++; + } + if (negative) + { + return rval * -1; + } + //else + return rval; +} diff --git a/qemu/roms/SLOF/lib/libc/stdlib/strtoul.c b/qemu/roms/SLOF/lib/libc/stdlib/strtoul.c new file mode 100644 index 000000000..754e7db4b --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/stdlib/strtoul.c @@ -0,0 +1,105 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <stdlib.h> + +unsigned long int strtoul(const char *S, char **PTR,int BASE) +{ + unsigned long rval = 0; + short int digit; + // *PTR is S, unless PTR is NULL, in which case i override it with my own ptr + char* ptr; + if (PTR == 0) + { + //override + PTR = &ptr; + } + // i use PTR to advance through the string + *PTR = (char *) S; + //check if BASE is ok + if ((BASE < 0) || BASE > 36) + { + return 0; + } + // ignore white space at beginning of S + while ((**PTR == ' ') + || (**PTR == '\t') + || (**PTR == '\n') + || (**PTR == '\r') + ) + { + (*PTR)++; + } + // if BASE is 0... determine the base from the first chars... + if (BASE == 0) + { + // if S starts with "0x", BASE = 16, else 10 + if ((**PTR == '0') && (*((*PTR)+1) == 'x')) + { + BASE = 16; + (*PTR)++; + (*PTR)++; + } + else + { + BASE = 10; + } + } + if (BASE == 16) + { + // S may start with "0x" + if ((**PTR == '0') && (*((*PTR)+1) == 'x')) + { + (*PTR)++; + (*PTR)++; + } + } + //until end of string + while (**PTR) + { + if (((**PTR) >= '0') && ((**PTR) <='9')) + { + //digit (0..9) + digit = **PTR - '0'; + } + else if (((**PTR) >= 'a') && ((**PTR) <='z')) + { + //alphanumeric digit lowercase(a (10) .. z (35) ) + digit = (**PTR - 'a') + 10; + } + else if (((**PTR) >= 'A') && ((**PTR) <='Z')) + { + //alphanumeric digit uppercase(a (10) .. z (35) ) + digit = (**PTR - 'A') + 10; + } + else + { + //end of parseable number reached... + break; + } + if (digit < BASE) + { + rval = (rval * BASE) + digit; + } + else + { + //digit found, but its too big for current base + //end of parseable number reached... + break; + } + //next... + (*PTR)++; + } + //done + return rval; +} + |