diff options
author | Adrian Reber <adrian@lisas.de> | 2008-11-23 14:12:45 +0100 |
---|---|---|
committer | Adrian Reber <adrian@lisas.de> | 2008-11-23 14:12:45 +0100 |
commit | e135f70200658ca6614e05700f20a3db7ea3d580 (patch) | |
tree | 60919627ea58a8c4a7f9ba4b748aa1e9105bfaf7 /lib | |
parent | c19a5bbc1f2650771d65a08a7c19563f28c01302 (diff) | |
download | SLOF-slof-JX-1.7.0-1.zip SLOF-slof-JX-1.7.0-1.tar.gz SLOF-slof-JX-1.7.0-1.tar.bz2 |
imported slof-JX-1.7.0-1 releaseslof-JX-1.7.0-1
Diffstat (limited to 'lib')
89 files changed, 2344 insertions, 463 deletions
diff --git a/lib/Makefile b/lib/Makefile index 4f3b4d8..34d3c23 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * 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 @@ -10,7 +10,8 @@ # * IBM Corporation - initial implementation # ****************************************************************************/ -SUBDIRS = libc libipmi libbootmsg libbases libelf +SUBDIRS = libc libipmi libbootmsg libbases libnvram libelf + all: subdirs diff --git a/lib/libbases/Makefile b/lib/libbases/Makefile index fe1845c..add4ed1 100644 --- a/lib/libbases/Makefile +++ b/lib/libbases/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * 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 @@ -15,8 +15,6 @@ TOPCMNDIR ?= ../.. include $(TOPCMNDIR)/make.rules ASFLAGS = $(FLAG) $(RELEASE) $(CPUARCHDEF) -Wa,-mregnames -CFLAGS = -g -O2 -fno-builtin -ffreestanding -nostdinc -msoft-float \ - -mno-altivec -mabi=no-altivec -Wall CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLBRDDIR) -I. -I../../include LDFLAGS = -nostdlib diff --git a/lib/libbases/libbases.code b/lib/libbases/libbases.code index 7f0a752..7dc941d 100644 --- a/lib/libbases/libbases.code +++ b/lib/libbases/libbases.code @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libbases/libbases.in b/lib/libbases/libbases.in index ed63de6..844a55d 100644 --- a/lib/libbases/libbases.in +++ b/lib/libbases/libbases.in @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libbootmsg/Makefile b/lib/libbootmsg/Makefile index 285a171..6804b8d 100644 --- a/lib/libbootmsg/Makefile +++ b/lib/libbootmsg/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * 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 @@ -12,11 +12,7 @@ TOPCMNDIR ?= ../.. -include $(TOPCMNDIR)/make.rules - ASFLAGS = $(FLAG) $(RELEASE) $(CPUARCHDEF) -Wa,-mregnames -CFLAGS = -g -O2 -fno-builtin -ffreestanding -nostdinc -msoft-float \ - -mno-altivec -mabi=no-altivec -Wall CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLBRDDIR) -I. -I../../include LDFLAGS = -nostdlib @@ -25,10 +21,24 @@ TARGET = ../libbootmsg.a all: $(TARGET) - -# SRCS = bootmsg.c +ifeq ($(CPUARCH),cbea) +SRCS = +SRCSS = bootmsg_lvl.S +else +ifeq ($(CPUARCH),ppc970) SRCS = SRCSS = bootmsg_lvl.S +else +ifeq ($(CPUARCH),p5) +SRCS = +SRCSS = bootmsg_lvl.S +else +SRCS = bootmsg.c +SRCSS = +endif +endif +endif + OBJS = $(SRCS:%.c=%.o) $(SRCSS:%.S=%.o) @@ -52,7 +62,7 @@ depend: $(MAKE) Makefile.dep Makefile.dep: Makefile - $(CC) -MM $(CPPFLAGS) $(CFLAGS) $(SRCSS) > Makefile.dep + $(CC) -MM $(CPPFLAGS) $(CFLAGS) $(SRCS) $(SRCSS) > Makefile.dep # Include dependency file if available: -include Makefile.dep diff --git a/lib/libbootmsg/bootmsg.code b/lib/libbootmsg/bootmsg.code index e43afa1..ae370af 100644 --- a/lib/libbootmsg/bootmsg.code +++ b/lib/libbootmsg/bootmsg.code @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -47,7 +47,15 @@ PRIM(bootmsg_X2d_setlevel) bootmsg_setlevel(area, lvl); MIRP -// : bootmsg-setlevel ( -- ) +// : bootmsg-checklevel ( area lvl -- [true|false] ) +PRIM(bootmsg_X2d_checklevel) + char lvl = TOS.n; POP; + short area = TOS.n; POP; + PUSH; + TOS.n = (bootmsg_checklevel(area, lvl)) ? -1 : 0; +MIRP + +// : bootmsg-nvupdate ( -- ) PRIM(bootmsg_X2d_nvupdate) bootmsg_nvupdate(); MIRP diff --git a/lib/libbootmsg/bootmsg.in b/lib/libbootmsg/bootmsg.in index 66492b3..73e01e3 100644 --- a/lib/libbootmsg/bootmsg.in +++ b/lib/libbootmsg/bootmsg.in @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -16,3 +16,4 @@ cod(bootmsg-error) cod(bootmsg-debugcp) cod(bootmsg-setlevel) cod(bootmsg-nvupdate) +cod(bootmsg-checklevel) diff --git a/lib/libbootmsg/bootmsg_lvl.S b/lib/libbootmsg/bootmsg_lvl.S index 1f8ec16..04ace12 100644 --- a/lib/libbootmsg/bootmsg_lvl.S +++ b/lib/libbootmsg/bootmsg_lvl.S @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -131,6 +131,23 @@ ENTRY(bootmsg_debugcp) ble print_msg // if UserLevel<=SystemLevel print and return blr // else return +//***************************************************************************** +// Check warning level +// input : r3=cp-id, r4=level +// change : r3,r4,r5,r6,r7,r9,r10,r11 +// output : r3 (true, false) +// r3=cp-id, r4=level +ENTRY(bootmsg_checklevel) + mflr r11 + mr r5, r4 + slwi r3, r3, 8 + bl GET_WRNG_LVL // check UserLevel against SystemLevel + li r3, 0 // return 0 + bgt 0f // IF ( UserLevel < SystemLevel ) + li r3, 1 // | return 1 +0: mtlr r11 // FI + blr + // r3=area|pkg, r4=level ENTRY(bootmsg_setlevel) mflr r5 @@ -150,7 +167,7 @@ ENTRY(bootmsg_setlevel) ENTRY(bootmsg_nvupdate) mflr r10 LOAD64(r3, SB_NVRAM_FWONLY_adr) - lbz r4, 0(r3) + lwz r4, 0(r3) cmpwi r4, 0x424E // find bootmsg area header bne 0f @@ -167,39 +184,11 @@ ENTRY(bootmsg_nvupdate) bdnz+ 1b b 2f -0: // find last partition an resize it - li r4, 0x10 - mtctr r4 - li r4, 0x0 - li r7, 0x0 - LOAD64(r5, SB_NVRAM_adr) - LOAD64(r8, NVRAM_LENGTH) -1: - bdz+ 2f - add r5, r5, r4 - lhz r6, 2(r5) - rldicl r6, r6, 4, 0 - mr r4, r6 - add r7, r7, r4 - cmpw r7, r8 - ble 1b - - sub r7, r7, r4 // write new size - sub r6, r8, r7 - sradi r6, r6, 4 - sth r6, 2(r5) - - mr r7, r3 - mr r8, r5 - mr r3, r5 - bl .calPartitionHeaderChecksum - stb r3, 1(r8) // write checksum - - mr r3, r7 +0: LOAD64(r5, bootmsg_area_size) mtctr r5 li r4, 0x424E // clear bootmsg log area - stb r4, 0(r3) + stw r4, 0(r3) li r4, 0 1: stdu r4, 8(r3) diff --git a/lib/libbootmsg/libbootmsg.h b/lib/libbootmsg/libbootmsg.h index be0ad7e..9d0bd15 100644 --- a/lib/libbootmsg/libbootmsg.h +++ b/lib/libbootmsg/libbootmsg.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -16,5 +16,6 @@ void bootmsg_error(short p, const char *str); void bootmsg_warning(short p, const char *str, short lvl); void bootmsg_debugcp(short p, const char *str, short lvl); void bootmsg_setlevel(short p, short level); -void *bootmsg_nvupdate(); +int bootmsg_checklevel(short p, short level); +void *bootmsg_nvupdate(void); #endif /* _LIBBOOTMSG_H */ diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 57b9694..0c762ec 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * 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 @@ -17,11 +17,11 @@ STRINGCMNDIR = $(LIBCCMNDIR)/string CTYPECMNDIR = $(LIBCCMNDIR)/ctype STDLIBCMNDIR = $(LIBCCMNDIR)/stdlib STDIOCMNDIR = $(LIBCCMNDIR)/stdio +GETOPTCMNDIR = $(LIBCCMNDIR)/getopt include $(TOPCMNDIR)/make.rules -CFLAGS = -g -O2 -fno-builtin -ffreestanding -nostdinc -msoft-float -mno-altivec -mabi=no-altivec -Wall CPPFLAGS = -I$(LIBCCMNDIR)/include LDFLAGS= -nostdlib @@ -40,8 +40,9 @@ include $(STRINGCMNDIR)/Makefile.inc include $(CTYPECMNDIR)/Makefile.inc include $(STDLIBCMNDIR)/Makefile.inc include $(STDIOCMNDIR)/Makefile.inc +include $(GETOPTCMNDIR)/Makefile.inc -OBJS = $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) +OBJS = $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) $(GETOPT_OBJS) ifneq ($(NATIVEBUILD),1) # These parts of the libc use assembler, so they can only be compiled when diff --git a/lib/libc/ctype/Makefile.inc b/lib/libc/ctype/Makefile.inc index 8486a8a..25513a9 100644 --- a/lib/libc/ctype/Makefile.inc +++ b/lib/libc/ctype/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * 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 @@ -11,7 +11,7 @@ # ****************************************************************************/ -CTYPE_SRC_C = isdigit.c isspace.c isxdigit.c tolower.c toupper.c +CTYPE_SRC_C = isdigit.c isprint.c isspace.c isxdigit.c tolower.c toupper.c CTYPE_SRC_ASM = CTYPE_SRCS = $(CTYPE_SRC_C:%=$(CTYPECMNDIR)/%) $(CTYPE_SRC_ASM:%=$(CTYPECMNDIR)/%) CTYPE_OBJS = $(CTYPE_SRC_C:%.c=%.o) $(CTYPE_SRC_ASM:%.S=%.o) diff --git a/lib/libc/ctype/isdigit.c b/lib/libc/ctype/isdigit.c index b3d1835..62d08a1 100644 --- a/lib/libc/ctype/isdigit.c +++ b/lib/libc/ctype/isdigit.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/ctype/isprint.c b/lib/libc/ctype/isprint.c new file mode 100644 index 0000000..c74880f --- /dev/null +++ b/lib/libc/ctype/isprint.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 <ctype.h> + +int isprint(int ch) +{ + return (ch >= 32 && ch < 127); +} diff --git a/lib/libc/ctype/isspace.c b/lib/libc/ctype/isspace.c index 0e749d7..5123019 100644 --- a/lib/libc/ctype/isspace.c +++ b/lib/libc/ctype/isspace.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/ctype/isxdigit.c b/lib/libc/ctype/isxdigit.c index 2b55d1a..9d323f3 100644 --- a/lib/libc/ctype/isxdigit.c +++ b/lib/libc/ctype/isxdigit.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/ctype/tolower.c b/lib/libc/ctype/tolower.c index f7eb03b..f775e90 100644 --- a/lib/libc/ctype/tolower.c +++ b/lib/libc/ctype/tolower.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/ctype/toupper.c b/lib/libc/ctype/toupper.c index 0eba9d0..9bcee52 100644 --- a/lib/libc/ctype/toupper.c +++ b/lib/libc/ctype/toupper.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/getopt/Makefile.inc b/lib/libc/getopt/Makefile.inc new file mode 100644 index 0000000..8a2e32f --- /dev/null +++ b/lib/libc/getopt/Makefile.inc @@ -0,0 +1,17 @@ +# ***************************************************************************** +# * 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 +# ****************************************************************************/ + +GETOPT_SRC_C = getopt.c +GETOPT_OBJS = $(GETOPT_SRC_C:%.c=%.o) + +%.o : $(GETOPTCMNDIR)/%.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ diff --git a/lib/libc/getopt/getopt.c b/lib/libc/getopt/getopt.c new file mode 100644 index 0000000..be626dd --- /dev/null +++ b/lib/libc/getopt/getopt.c @@ -0,0 +1,470 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +/* + * includes + ******************************************************************************* + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> + +/* + * global variables, types & constants + * may be removed if already defined + ******************************************************************************* + */ +int opterr = 1; +int optopt = 0; +int optind = 1; +char *optarg = NULL; + +/* + * internal values needed by getopt + * DO NOT CHANGE or REMOVE + */ +enum { + OPTIONAL_ARG = 0, + MANDATORY_ARG = 1, + NO_ARG = 2 +}; + +/* + * variables needed by getopt & getopt_long! + * DO NOT REMOVE + */ +static char *optstart = NULL; + +int +getopt(int argc, char **argv, const char *options) +{ + char *optptr; + char *argptr; + int optman; + int idx; + int ret = 0; + int argpresent; + + /* + * reset used global values + */ + optopt = 0; + optarg = NULL; + + /* + * reset getopt if a new argv pointer is passed + */ + if (optstart != argv[0]) { + optopt = 0; + optind = 1; + optarg = NULL; + optstart = argv[0]; + } + + /* + * return if no more arguments are available + */ + if (optind >= argc) { + return -1; + } + + /* + * start parsing argv[optind] + */ + idx = 0; + + /* + * return if the option does not begin with a '-' or has more than 2 characters + */ + if (argv[optind][idx] != '-') { + + if (opterr != 0) { + printf("unknown option \'%s\', expecting \'-\'\n", + argv[optind]); + } + + optopt = (int) argv[optind][idx]; + optind++; + + return '?'; + } + + /* + * continue to the next character in argv[optind] + */ + idx++; + + /* + * identify the option + * make sure if an option contains a ':' to invalidate the option + */ + optptr = strchr(argv[optind], ':'); + + if (optptr == NULL) { + optptr = strchr(options, (int) argv[optind][idx]); + } else { + optptr = NULL; + } + + /* + * check whether the option is present + */ + if (optptr == NULL) { + /* + * unknown option detected + */ + if (opterr != 0) { + printf("unknown option \'%s\'\n", argv[optind]); + } + + optopt = (int) argv[optind][idx]; + optind++; + + return '?'; + } + + /* + * the option is present in the option string + * setup return value + */ + ret = (int) *optptr; + + /* + * get option argument if needed + */ + optptr++; + + /* + * determine between mandatory and optional argument + */ + optman = NO_ARG; + + if (*optptr == ':') { + optman--; // now set to MANDATORY_ARG + } + + if (optman == MANDATORY_ARG) { + optptr++; + + if (*optptr == ':') { + optman--; // now set to OPTIONAL_ARG + } + + } + + /* + * if strlen( argv[optind ) is greater than 2, + * the argument is in the same argv + */ + if (strlen(argv[optind]) > 2) { + argptr = &argv[optind][2]; + + /* + * do not allow '-' in an argument + */ + if (strchr(argptr, '-') != NULL) { + + if (opterr != 0) { + printf + ("illegal argument value \'%s\' for option \'-%c\'\n", + argptr, ret); + } + + optopt = ret; + + return '?'; + } + + } else { + /* + * move on to the next argv + * it now either contains an argument or the next option + */ + optind++; + + /* + * make sure not to overflow + */ + if (optind < argc) { + argptr = argv[optind]; + } else { + argptr = NULL; + } + + } + + /* + * do the needed actions for the argument state + */ + switch (optman) { + case OPTIONAL_ARG: + + if (argptr == NULL) { + break; + } + + if (*argptr != '-') { + /* + * argument present + */ + optarg = argptr; + optind++; + + } + + + break; + + case MANDATORY_ARG: + argpresent = (argptr != NULL); + + if (argpresent) { + argpresent = (*argptr != '-'); + } + + if (argpresent) { + /* + * argument present + */ + optarg = argptr; + optind++; + } else { + /* + * mandatory argument missing + */ + if (opterr != 0) { + printf + ("missing argument for option \'-%c\'\n", + ret); + } + + optopt = ret; + + /* + * if the first character of options is a ':' + * return a ':' instead of a '?' in case of + * a missing argument + */ + if (*options == ':') { + ret = ':'; + } else { + ret = '?'; + } + + } + + + break; + + case NO_ARG: + + if (strlen(argv[optind - 1]) > 2) { + + if (opterr != 0) { + printf + ("too many arguments for option \'-%c\'\n", + ret); + } + + optopt = ret; + ret = '?'; + } + + + break; + + } + + return ret; +} + +int +getopt_long(int argc, char **argv, const char *shortopts, + const struct option *longopts, int *indexptr) +{ + struct option *optptr = (struct option *) longopts; + int optidx = 0; + int idx; + int ret = 0; + int argpresent; + + /* + * reset used global values + */ + optopt = 0; + optarg = NULL; + + /* + * reset indexptr + */ + *indexptr = -1; + + /* + * reset getopt if a new argv pointer is passed + */ + if (optstart != argv[0]) { + optopt = 0; + optind = 1; + optarg = NULL; + optstart = argv[0]; + } + + /* + * return if no more arguments are available + */ + if (optind >= argc) { + return -1; + } + + /* + * start parsing argv[optind] + */ + idx = 0; + + /* + * return if the option does not begin with a '-' + */ + if (argv[optind][idx] != '-') { + printf("unknown option \'%s\', expecting \'-\'\n", + argv[optind]); + + optind++; + + return '?'; + } + + /* + * move on to the next character in argv[optind] + */ + idx++; + + /* + * return getopt() in case of a short option + */ + if (argv[optind][idx] != '-') { + return getopt(argc, argv, shortopts); + } + + /* + * handle a long option + */ + idx++; + + while (optptr->name != NULL) { + + if (strcmp(&argv[optind][idx], optptr->name) == 0) { + break; + } + + optptr++; + optidx++; + } + + /* + * no matching option found + */ + if (optptr->name == NULL) { + printf("unknown option \'%s\'\n", argv[optind]); + + optind++; + + return '?'; + } + + /* + * option was found, set up index pointer + */ + *indexptr = optidx; + + /* + * get argument + */ + optind++; + + switch (optptr->has_arg) { + case no_argument: + /* + * nothing to do + */ + + break; + + case required_argument: + argpresent = (optind != argc); + + if (argpresent) { + argpresent = (argv[optind][0] != '-'); + } + + if (argpresent) { + /* + * argument present + */ + optarg = argv[optind]; + optind++; + } else { + /* + * mandatory argument missing + */ + printf("missing argument for option \'%s\'\n", + argv[optind - 1]); + + ret = '?'; + } + + + break; + + case optional_argument: + + if (optind == argc) { + break; + } + + if (argv[optind][0] != '-') { + /* + * argument present + */ + optarg = argv[optind]; + optind++; + } + + + break; + + default: + printf("unknown argument option for option \'%s\'\n", + argv[optind - 1]); + + ret = '?'; + + break; + + } + + /* + * setup return values + */ + if (ret != '?') { + + if (optptr->flag == NULL) { + ret = optptr->val; + } else { + *optptr->flag = optptr->val; + ret = 0; + } + + } + + return ret; +} diff --git a/lib/libc/include/ctype.h b/lib/libc/include/ctype.h index 3e5e47b..9051a75 100644 --- a/lib/libc/include/ctype.h +++ b/lib/libc/include/ctype.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -15,6 +15,7 @@ int isdigit(int c); int isxdigit(int c); +int isprint(int c); int isspace(int c); int tolower(int c); diff --git a/lib/libc/include/errno.h b/lib/libc/include/errno.h index eea7a36..d585934 100644 --- a/lib/libc/include/errno.h +++ b/lib/libc/include/errno.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/include/getopt.h b/lib/libc/include/getopt.h new file mode 100644 index 0000000..5956986 --- /dev/null +++ b/lib/libc/include/getopt.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +#ifndef GETOPT_H +#define GETOPT_H + +extern char *optarg; +extern int optind; +extern int opterr; +extern int optopt; + +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; + +enum { + no_argument = 0, + required_argument, + optional_argument +}; + +int getopt(int argc, char **, const char *); +int getopt_long(int argc, char **, const char *, const struct option *, int *); + +#endif /* GETOPT_H */ diff --git a/lib/libc/include/limits.h b/lib/libc/include/limits.h index ce694ea..4726835 100644 --- a/lib/libc/include/limits.h +++ b/lib/libc/include/limits.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/include/stdarg.h b/lib/libc/include/stdarg.h index 422c598..d3d12f7 100644 --- a/lib/libc/include/stdarg.h +++ b/lib/libc/include/stdarg.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/include/stddef.h b/lib/libc/include/stddef.h index 318e2bb..ba2d960 100644 --- a/lib/libc/include/stddef.h +++ b/lib/libc/include/stddef.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/include/stdint.h b/lib/libc/include/stdint.h index e455f19..518a723 100644 --- a/lib/libc/include/stdint.h +++ b/lib/libc/include/stdint.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/include/stdio.h b/lib/libc/include/stdio.h index 096e035..84cddea 100644 --- a/lib/libc/include/stdio.h +++ b/lib/libc/include/stdio.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/include/stdlib.h b/lib/libc/include/stdlib.h index ad0ef4f..dff57f5 100644 --- a/lib/libc/include/stdlib.h +++ b/lib/libc/include/stdlib.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -23,6 +23,8 @@ void *realloc(void *ptr, size_t size); void free(void *ptr); void *memalign(size_t boundary, size_t size); +int atoi(const char *str); +long atol(const char *str); unsigned long int strtoul(const char *nptr, char **endptr, int base); long int strtol(const char *nptr, char **endptr, int base); diff --git a/lib/libc/include/string.h b/lib/libc/include/string.h index d792b1b..ebc7568 100644 --- a/lib/libc/include/string.h +++ b/lib/libc/include/string.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/include/unistd.h b/lib/libc/include/unistd.h index c09c45d..f1b1c62 100644 --- a/lib/libc/include/unistd.h +++ b/lib/libc/include/unistd.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc index 8783570..ac5302d 100644 --- a/lib/libc/stdio/Makefile.inc +++ b/lib/libc/stdio/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * 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 diff --git a/lib/libc/stdio/fileno.c b/lib/libc/stdio/fileno.c index de77906..6e23951 100644 --- a/lib/libc/stdio/fileno.c +++ b/lib/libc/stdio/fileno.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/fprintf.c b/lib/libc/stdio/fprintf.c index 2337464..866df39 100644 --- a/lib/libc/stdio/fprintf.c +++ b/lib/libc/stdio/fprintf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/fscanf.c b/lib/libc/stdio/fscanf.c index e2e28de..321b163 100644 --- a/lib/libc/stdio/fscanf.c +++ b/lib/libc/stdio/fscanf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/printf.c b/lib/libc/stdio/printf.c index e73798b..01f4592 100644 --- a/lib/libc/stdio/printf.c +++ b/lib/libc/stdio/printf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/putc.c b/lib/libc/stdio/putc.c index b21e37b..230e9d1 100644 --- a/lib/libc/stdio/putc.c +++ b/lib/libc/stdio/putc.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/putchar.c b/lib/libc/stdio/putchar.c index 524423e..5c750d9 100644 --- a/lib/libc/stdio/putchar.c +++ b/lib/libc/stdio/putchar.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/puts.c b/lib/libc/stdio/puts.c index bf2b8af..3f48dbf 100644 --- a/lib/libc/stdio/puts.c +++ b/lib/libc/stdio/puts.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/scanf.c b/lib/libc/stdio/scanf.c index 9ff8f00..96b6399 100644 --- a/lib/libc/stdio/scanf.c +++ b/lib/libc/stdio/scanf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/setvbuf.c b/lib/libc/stdio/setvbuf.c index fcc10f5..9b62dd8 100644 --- a/lib/libc/stdio/setvbuf.c +++ b/lib/libc/stdio/setvbuf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c index c84255b..9c4540e 100644 --- a/lib/libc/stdio/sprintf.c +++ b/lib/libc/stdio/sprintf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/stdchnls.c b/lib/libc/stdio/stdchnls.c index 9b45be0..41ed958 100644 --- a/lib/libc/stdio/stdchnls.c +++ b/lib/libc/stdio/stdchnls.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index 9a657ec..765feea 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c index 7a9f237..4ddd210 100644 --- a/lib/libc/stdio/vfscanf.c +++ b/lib/libc/stdio/vfscanf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -18,20 +18,20 @@ static int -_getc(FILE *stream) +_getc(FILE * stream) { int count; char c; if (stream->mode == _IONBF || stream->buf == NULL) { - if (read(stream->fd,&c,1) == 1) - return (int)c; + if (read(stream->fd, &c, 1) == 1) + return (int) c; else return EOF; } if (stream->pos == 0 || stream->pos >= BUFSIZ || - stream->buf[stream->pos] == '\0') { + stream->buf[stream->pos] == '\0') { count = read(stream->fd, stream->buf, BUFSIZ); if (count < 0) count = 0; @@ -44,16 +44,16 @@ _getc(FILE *stream) } static void -_ungetc(int ch, FILE *stream) +_ungetc(int ch, FILE * stream) { - if(stream->mode != _IONBF && stream->pos > 0) + if (stream->mode != _IONBF && stream->pos > 0) stream->pos--; } static int _is_voidage(int ch) { - if(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0') + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\0') return 1; else return 0; @@ -61,143 +61,150 @@ _is_voidage(int ch) static int -_scanf(FILE *stream, const char *fmt, va_list *ap) +_scanf(FILE * stream, const char *fmt, va_list * ap) { - int i=0; + int i = 0; int length = 0; - fmt++; + fmt++; + + while (*fmt != '\0') { - while(*fmt != '\0') { - char tbuf[256]; char ch; - switch(*fmt) { - case 'd': - case 'i': - ch = _getc(stream); - if(length == 0) { - while(!_is_voidage(ch) && isdigit(ch)) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } - } else { - while(!_is_voidage(ch) && i < length && isdigit(ch)) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } + switch (*fmt) { + case 'd': + case 'i': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch) && isdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; } - _ungetc(ch, stream); - tbuf[i] = '\0'; - - ch = _getc(stream); - if(!_is_voidage(ch)) - _ungetc(ch, stream); - - if(strlen(tbuf) == 0) - return 0; - - *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 10); - break; - case 'X': - case 'x': - ch = _getc(stream); - if(length == 0) { - while(!_is_voidage(ch) && isxdigit(ch)) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } - } else { - while(!_is_voidage(ch) && i < length && isxdigit(ch)) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } + } else { + while (!_is_voidage(ch) && i < length + && isdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; } + } + /* We tried to understand what this is good for... + * but we did not. We know for sure that it does not + * work on SLOF if this is active. */ + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) _ungetc(ch, stream); - tbuf[i] = '\0'; - - ch = _getc(stream); - if(!_is_voidage(ch)) - _ungetc(ch, stream); - - if(strlen(tbuf) == 0) - return 0; - - *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 16); - break; - case 'O': - case 'o': - ch = _getc(stream); - if(length == 0) { - while(!_is_voidage(ch) && !(ch < '0' || ch > '7')) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } - } else { - while(!_is_voidage(ch) && i < length && !(ch < '0' || ch > '7')) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } + + if (strlen(tbuf) == 0) + return 0; + + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 10); + break; + case 'X': + case 'x': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch) && isxdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } else { + while (!_is_voidage(ch) && i < length + && isxdigit(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; } + } + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) _ungetc(ch, stream); - tbuf[i] = '\0'; - - ch = _getc(stream); - if(!_is_voidage(ch)) - _ungetc(ch, stream); - if(strlen(tbuf) == 0) - return 0; + if (strlen(tbuf) == 0) + return 0; - *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 8); - break; - case 'c': - ch = _getc(stream); - while(_is_voidage(ch)) + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 16); + break; + case 'O': + case 'o': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch) + && !(ch < '0' || ch > '7')) { + tbuf[i] = ch; ch = _getc(stream); - - *(va_arg(*ap, char *)) = ch; - - ch = _getc(stream); - if(!_is_voidage(ch)) - _ungetc(ch, stream); + i++; + } + } else { + while (!_is_voidage(ch) && i < length + && !(ch < '0' || ch > '7')) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) + _ungetc(ch, stream); + + if (strlen(tbuf) == 0) + return 0; - break; - case 's': + *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 8); + break; + case 'c': + ch = _getc(stream); + while (_is_voidage(ch)) ch = _getc(stream); - if(length == 0) { - while(!_is_voidage(ch)) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } - } else { - while(!_is_voidage(ch) && i < length) { - tbuf[i] = ch; - ch = _getc(stream); - i++; - } + + *(va_arg(*ap, char *)) = ch; + + ch = _getc(stream); + if (!_is_voidage(ch)) + _ungetc(ch, stream); + + break; + case 's': + ch = _getc(stream); + if (length == 0) { + while (!_is_voidage(ch)) { + tbuf[i] = ch; + ch = _getc(stream); + i++; + } + } else { + while (!_is_voidage(ch) && i < length) { + tbuf[i] = ch; + ch = _getc(stream); + i++; } + } + /* _ungetc(ch, stream); */ + tbuf[i] = '\0'; + + /* ch = _getc(stream); */ + if (!_is_voidage(ch)) _ungetc(ch, stream); - tbuf[i] = '\0'; - - ch = _getc(stream); - if(!_is_voidage(ch)) - _ungetc(ch, stream); - - strcpy(va_arg(*ap, char *), tbuf); - break; - default: - if(*fmt >= '0' && *fmt <= '9') - length += *fmt - '0'; - break; + + strcpy(va_arg(*ap, char *), tbuf); + break; + default: + if (*fmt >= '0' && *fmt <= '9') + length += *fmt - '0'; + break; } fmt++; } @@ -208,34 +215,36 @@ _scanf(FILE *stream, const char *fmt, va_list *ap) int -vfscanf(FILE *stream, const char *fmt, va_list ap) +vfscanf(FILE * stream, const char *fmt, va_list ap) { int args = 0; - while(*fmt != '\0') { - - if(*fmt == '%') { - + while (*fmt != '\0') { + + if (*fmt == '%') { + char formstr[20]; - int i=0; - + int i = 0; + do { formstr[i] = *fmt; fmt++; i++; - } while(!(*fmt == 'd' || *fmt == 'i' || *fmt == 'x' || *fmt == 'X' - || *fmt == 'p' || *fmt == 'c' || *fmt == 's' || *fmt == '%' - || *fmt == 'O' || *fmt == 'o' )); + } while (! + (*fmt == 'd' || *fmt == 'i' || *fmt == 'x' + || *fmt == 'X' || *fmt == 'p' || *fmt == 'c' + || *fmt == 's' || *fmt == '%' || *fmt == 'O' + || *fmt == 'o')); formstr[i++] = *fmt; formstr[i] = '\0'; - if(*fmt != '%') { - if(_scanf(stream, formstr, &ap) <= 0) + if (*fmt != '%') { + if (_scanf(stream, formstr, &ap) <= 0) return args; else args++; } - } + } fmt++; @@ -244,13 +253,14 @@ vfscanf(FILE *stream, const char *fmt, va_list ap) return args; } -int getc(FILE *stream) +int +getc(FILE * stream) { return _getc(stream); } -int getchar(void) +int +getchar(void) { return _getc(stdin); } - diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c index 200512f..e78fb3d 100644 --- a/lib/libc/stdio/vsnprintf.c +++ b/lib/libc/stdio/vsnprintf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c index c565a89..0dfd737 100644 --- a/lib/libc/stdio/vsprintf.c +++ b/lib/libc/stdio/vsprintf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c index 68760b5..b9603e9 100644 --- a/lib/libc/stdio/vsscanf.c +++ b/lib/libc/stdio/vsscanf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 5b854fc..702f6d7 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * 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 @@ -11,7 +11,7 @@ # ****************************************************************************/ -STDLIB_SRC_C = error.c strtoul.c strtol.c rand.c \ +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 = diff --git a/lib/libc/stdlib/atoi.c b/lib/libc/stdlib/atoi.c new file mode 100644 index 0000000..d2fb33b --- /dev/null +++ b/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/lib/libc/stdlib/atol.c b/lib/libc/stdlib/atol.c new file mode 100644 index 0000000..a6aa47b --- /dev/null +++ b/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/lib/libc/stdlib/error.c b/lib/libc/stdlib/error.c index d440f7c..81020ca 100644 --- a/lib/libc/stdlib/error.c +++ b/lib/libc/stdlib/error.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdlib/free.c b/lib/libc/stdlib/free.c index 7aff279..9005450 100644 --- a/lib/libc/stdlib/free.c +++ b/lib/libc/stdlib/free.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c index 4bc4b79..b2a3138 100644 --- a/lib/libc/stdlib/malloc.c +++ b/lib/libc/stdlib/malloc.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdlib/malloc_defs.h b/lib/libc/stdlib/malloc_defs.h index 59fcd91..1933026 100644 --- a/lib/libc/stdlib/malloc_defs.h +++ b/lib/libc/stdlib/malloc_defs.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdlib/memalign.c b/lib/libc/stdlib/memalign.c index 0bb430e..3b678aa 100644 --- a/lib/libc/stdlib/memalign.c +++ b/lib/libc/stdlib/memalign.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c index d3a0254..87e3efd 100644 --- a/lib/libc/stdlib/rand.c +++ b/lib/libc/stdlib/rand.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdlib/realloc.c b/lib/libc/stdlib/realloc.c index d1dfdfb..652e900 100644 --- a/lib/libc/stdlib/realloc.c +++ b/lib/libc/stdlib/realloc.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/stdlib/strtol.c b/lib/libc/stdlib/strtol.c index ee14a39..aae5e54 100644 --- a/lib/libc/stdlib/strtol.c +++ b/lib/libc/stdlib/strtol.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -9,106 +9,105 @@ * Contributors: * IBM Corporation - initial implementation *****************************************************************************/ -
-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;
-}
-
+ +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/lib/libc/stdlib/strtoul.c b/lib/libc/stdlib/strtoul.c index 74cdccd..3a86c50 100644 --- a/lib/libc/stdlib/strtoul.c +++ b/lib/libc/stdlib/strtoul.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -9,95 +9,95 @@ * Contributors: * IBM Corporation - initial implementation *****************************************************************************/ -
-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;
-}
-
+ +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; +} + diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc index e857bbc..7ccf3c4 100644 --- a/lib/libc/string/Makefile.inc +++ b/lib/libc/string/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * 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 @@ -13,7 +13,7 @@ STRING_SRC_C = strcat.c strchr.c strcmp.c strcpy.c strlen.c strncmp.c \ strncpy.c strstr.c memset.c memcpy.c memmove.c memchr.c \ - memcmp.c strcasecmp.c strncasecmp.c + memcmp.c strcasecmp.c strncasecmp.c strtok.c STRING_SRC_ASM = STRING_SRCS = $(STRING_SRC_C:%=$(STRINGCMNDIR)/%) $(STRING_SRC_ASM:%=$(STRINGCMNDIR)/%) STRING_OBJS = $(STRING_SRC_C:%.c=%.o) $(STRING_SRC_ASM:%.S=%.o) diff --git a/lib/libc/string/memchr.c b/lib/libc/string/memchr.c index d4e9b7f..c3fe751 100644 --- a/lib/libc/string/memchr.c +++ b/lib/libc/string/memchr.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/memcmp.c b/lib/libc/string/memcmp.c index b64d560..3b69cef 100644 --- a/lib/libc/string/memcmp.c +++ b/lib/libc/string/memcmp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/memcpy.c b/lib/libc/string/memcpy.c index 36a4a3c..00f419b 100644 --- a/lib/libc/string/memcpy.c +++ b/lib/libc/string/memcpy.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/memmove.c b/lib/libc/string/memmove.c index 7ceee33..3acf1a9 100644 --- a/lib/libc/string/memmove.c +++ b/lib/libc/string/memmove.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/memset.c b/lib/libc/string/memset.c index 0f5a660..f8dfbf5 100644 --- a/lib/libc/string/memset.c +++ b/lib/libc/string/memset.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/strcasecmp.c b/lib/libc/string/strcasecmp.c index 98cde44..f75294f 100644 --- a/lib/libc/string/strcasecmp.c +++ b/lib/libc/string/strcasecmp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/strcat.c b/lib/libc/string/strcat.c index eadd6b9..eb597a0 100644 --- a/lib/libc/string/strcat.c +++ b/lib/libc/string/strcat.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/strchr.c b/lib/libc/string/strchr.c index 214eaa9..528a319 100644 --- a/lib/libc/string/strchr.c +++ b/lib/libc/string/strchr.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/strcmp.c b/lib/libc/string/strcmp.c index 4a765ea..48eaed2 100644 --- a/lib/libc/string/strcmp.c +++ b/lib/libc/string/strcmp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/strcpy.c b/lib/libc/string/strcpy.c index 4c888ca..48eb62c 100644 --- a/lib/libc/string/strcpy.c +++ b/lib/libc/string/strcpy.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/strlen.c b/lib/libc/string/strlen.c index c091f75..37a1b78 100644 --- a/lib/libc/string/strlen.c +++ b/lib/libc/string/strlen.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/strncasecmp.c b/lib/libc/string/strncasecmp.c index 1aa6639..4140931 100644 --- a/lib/libc/string/strncasecmp.c +++ b/lib/libc/string/strncasecmp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/strncmp.c b/lib/libc/string/strncmp.c index 357d113..a886736 100644 --- a/lib/libc/string/strncmp.c +++ b/lib/libc/string/strncmp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/strncpy.c b/lib/libc/string/strncpy.c index a2667d8..0f41f93 100644 --- a/lib/libc/string/strncpy.c +++ b/lib/libc/string/strncpy.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/strstr.c b/lib/libc/string/strstr.c index f94af6d..3e090d2 100644 --- a/lib/libc/string/strstr.c +++ b/lib/libc/string/strstr.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libc/string/strtok.c b/lib/libc/string/strtok.c new file mode 100644 index 0000000..665c08d --- /dev/null +++ b/lib/libc/string/strtok.c @@ -0,0 +1,45 @@ +/****************************************************************************** + * 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 <string.h> + +char * +strtok(char *src, const char *pattern) +{ + static char *nxtTok; + char *retVal = NULL; + + if (!src) + src = nxtTok; + + while (*src) { + const char *pp = pattern; + while (*pp) { + if (*pp == *src) { + break; + } + pp++; + } + if (!*pp) { + if (!retVal) + retVal = src; + else if (!src[-1]) + break; + } else + *src = '\0'; + src++; + } + + nxtTok = src; + + return retVal; +} diff --git a/lib/libelf/Makefile b/lib/libelf/Makefile index 3bd56ce..82ef0bb 100644 --- a/lib/libelf/Makefile +++ b/lib/libelf/Makefile @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2007 IBM Corporation +# * 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 @@ -14,9 +14,7 @@ TOPCMNDIR ?= ../.. include $(TOPCMNDIR)/make.rules -CFLAGS = -g -O2 -fno-builtin -ffreestanding -nostdinc -msoft-float \ - -mno-altivec -mabi=no-altivec -Wall -CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLCMNDIR)/$(CPUARCH) +CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLCMNDIR) -I$(INCLCMNDIR)/$(CPUARCH) LDFLAGS= -nostdlib TARGET = ../libelf.a diff --git a/lib/libelf/elf.c b/lib/libelf/elf.c index 93e5762..359f628 100644 --- a/lib/libelf/elf.c +++ b/lib/libelf/elf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -14,6 +14,7 @@ #include <string.h> #include <cpu.h> +#include <libelf.h> struct ehdr { unsigned int ei_ident; diff --git a/lib/libelf/libelf.code b/lib/libelf/libelf.code index 01efdf3..6e019fc 100644 --- a/lib/libelf/libelf.code +++ b/lib/libelf/libelf.code @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libelf/libelf.in b/lib/libelf/libelf.in index 1b74d51..1fea40c 100644 --- a/lib/libelf/libelf.in +++ b/lib/libelf/libelf.in @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 diff --git a/lib/libipmi/libipmi.code b/lib/libipmi/libipmi.code index 761a50d..59c1244 100644 --- a/lib/libipmi/libipmi.code +++ b/lib/libipmi/libipmi.code @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -103,3 +103,18 @@ PRIM(IPMI_X2d_OEM_X2d_BIOS2SP) TOS.n = ipmi_oem_bios2sp(swid, type, addr, len); MIRP +// : ipmi-set-sensor ( param-1 ... param-n n command sensor - errorcode ) +PRIM(IPMI_X2d_SET_X2d_SENSOR) + int sensor = TOS.n; POP; + int cmd = TOS.n; POP; + int n = TOS.n; + int i = n; + uint8_t param[10]; + while (i>0) { + i--; + POP; param[i]=TOS.n; + }; + TOS.n = ipmi_set_sensor((cmd<<8)+sensor,n, + param[0],param[1],param[2],param[3],param[4], + param[5],param[6],param[7],param[8],param[9]); +MIRP diff --git a/lib/libipmi/libipmi.h b/lib/libipmi/libipmi.h index 5651180..9ac8308 100644 --- a/lib/libipmi/libipmi.h +++ b/lib/libipmi/libipmi.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -19,6 +19,7 @@ extern int ipmi_kcs_cmd(uint8_t *, uint8_t *, uint32_t, uint32_t *); extern void ipmi_system_reboot(void); extern void ipmi_power_off(void); +extern int ipmi_set_sensor(const int sensor, int number_of_args, ...); extern int ipmi_oem_stop_bootwatchdog(void); extern int ipmi_oem_set_bootwatchdog(uint16_t seconds); diff --git a/lib/libipmi/libipmi.in b/lib/libipmi/libipmi.in index a0d0f12..5b0e0ec 100644 --- a/lib/libipmi/libipmi.in +++ b/lib/libipmi/libipmi.in @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2007 IBM Corporation + * 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 @@ -21,3 +21,4 @@ cod(IPMI-OEM-READ-VPD) cod(IPMI-OEM-WRITE-VPD) cod(IPMI-OEM-GET-BLADE-DESCR) cod(IPMI-OEM-BIOS2SP) +cod(IPMI-SET-SENSOR) diff --git a/lib/libnvram/Makefile b/lib/libnvram/Makefile new file mode 100644 index 0000000..6c9ec84 --- /dev/null +++ b/lib/libnvram/Makefile @@ -0,0 +1,49 @@ +# ***************************************************************************** +# * 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 +# ****************************************************************************/ + +SRCS = nvram.c envvar.c + +TOPCMNDIR ?= ../.. + +ASFLAGS = $(FLAG) $(RELEASE) $(CPUARCHDEF) -Wa,-mregnames +CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLBRDDIR) -I$(INCLCMNDIR)/$(CPUARCH) -I. -I../../include +LDFLAGS = -nostdlib + +TARGET = ../libnvram.a + +all: $(TARGET) + +OBJS = $(SRCS:%.c=%.o) + +$(TARGET): $(OBJS) + $(AR) -rc $@ $(OBJS) + $(RANLIB) $@ + + +clean: + $(RM) $(TARGET) $(OBJS) + +distclean: clean + $(RM) Makefile.dep + + +# Rules for creating the dependency file: +depend: + $(RM) Makefile.dep + $(MAKE) Makefile.dep + +Makefile.dep: Makefile + + +# Include dependency file if available: +-include Makefile.dep + diff --git a/lib/libnvram/envvar.c b/lib/libnvram/envvar.c new file mode 100644 index 0000000..eec7db7 --- /dev/null +++ b/lib/libnvram/envvar.c @@ -0,0 +1,244 @@ +/****************************************************************************** + * 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 <stdint.h> +#include "../libc/include/stdio.h" +#include "../libc/include/string.h" +#include "../libc/include/stdlib.h" +#include "nvram.h" + +/* returns the offset of the first byte after the searched envvar */ +static int get_past_env_pos(partition_t part, char *envvar) +{ + int offset, len; + static char temp[256]; + uint8_t data; + + offset=part.addr; + + memset(temp, 0, 256); + + do { + len=0; + while((data=nvram_read_byte(offset++)) && len < 256) { + temp[len++]=data; + } + if (!strncmp(envvar, temp, strlen(envvar))) { + return offset; + } + } while (len); + + return -1; +} + +/** + * @param partition name of the envvar partition + * @param envvar name of the environment variable + * @return pointer to temporary string containing the value of envvar + */ + +char *get_env(partition_t part, char *envvar) +{ + static char temp[256+1]; + int len, offset; + uint8_t data; + + DEBUG("get_env %s... ", envvar); + if(!part.addr) { + /* ERROR: No environment variable partition */ + DEBUG("invalid partition.\n"); + return NULL; + } + + offset=part.addr; + + do { + len=0; + while((data=nvram_read_byte(offset++)) && len < 256) { + temp[len++]=data; + } + temp[len]=0; + + if (!strncmp(envvar, temp, strlen(envvar))) { + int pos=0; + while (temp[pos]!='=' && pos < len) pos++; + // DEBUG("value='%s'\n", temp+pos+1); + return temp+pos+1; + } + } while (len); + + DEBUG("not found\n"); + return NULL; +} + +static int find_last_envvar(partition_t part) +{ + uint8_t last, current; + int offset, len; + + offset=part.addr; + len=part.len; + + last=nvram_read_byte(part.addr); + + for (offset=part.addr; offset<(int)(part.addr+part.len); offset++) { + current=nvram_read_byte(offset); + if(!last && !current) + return offset; + + last=current; + } + + return -1; +} + +int add_env(partition_t part, char *envvar, char *value) +{ + int freespace, last, len, offset; + unsigned int i; + + /* Find offset where we can write */ + last = find_last_envvar(part); + + /* How much space do we have left? */ + freespace = part.addr+part.len-last; + + /* how long is the entry we want to write? */ + len = strlen(envvar) + strlen(value) + 2; + + if(freespace<len) { + // TODO try to increase partition size + return -1; + } + + offset=last; + + for(i=0; i<strlen(envvar); i++) + nvram_write_byte(offset++, envvar[i]); + + nvram_write_byte(offset++, '='); + + for(i=0; i<strlen(value); i++) + nvram_write_byte(offset++, value[i]); + + return 0; +} + +int del_env(partition_t part, char *envvar) +{ + int last, current, pos, i; + char *buffer; + + if(!part.addr) + return -1; + + last=find_last_envvar(part); + current = pos = get_past_env_pos(part, envvar); + + // TODO is this really required? + /* go back to non-0 value */ + current--; + + while (nvram_read_byte(current)) + current--; + + // TODO is this required? + current++; + + buffer=get_nvram_buffer(last-pos); + + for (i=0; i<last-pos; i++) + buffer[i]=nvram_read_byte(i+pos); + + for (i=0; i<last-pos; i++) + nvram_write_byte(i+current, buffer[i]); + + free_nvram_buffer(buffer); + + erase_nvram(last, current+last-pos); + + return 0; +} + +int set_env(partition_t part, char *envvar, char *value) +{ + char *oldvalue, *buffer; + int last, current, buffersize, i; + + DEBUG("set_env %lx[%lx]: %s=%s\n", part.addr, part.len, envvar, value); + + if(!part.addr) + return -1; + + /* Check whether the environment variable exists already */ + oldvalue = get_env(part, envvar); + + if(oldvalue==NULL) + return add_env(part, envvar, value); + + + /* The value did not change. So we succeeded! */ + if(!strncmp(oldvalue, value, strlen(value)+1)) + return 0; + + /* we need to overwrite environment variables, back them up first */ + + // DEBUG("overwriting existing environment variable\n"); + + /* allocate a buffer */ + last=find_last_envvar(part); + current=get_past_env_pos(part, envvar); + buffersize = last - current; + buffer=get_nvram_buffer(buffersize); + if(!buffer) + return -1; + + for (i=0; i<buffersize; i++) { + buffer[i] = nvram_read_byte(current+i); + } + + /* walk back until the = */ + while (nvram_read_byte(current)!='=') { + current--; + } + + /* Start at envvar= */ + current++; + + /* Write the new value */ + for(i=0; i<(int)strlen(value); i++) { + nvram_write_byte(current++, value[i]); + } + + /* Write end of string marker */ + nvram_write_byte(current++, 0); + + /* Copy back the buffer */ + for (i=0; i<buffersize; i++) { + nvram_write_byte(current++, buffer[i]); + } + + free_nvram_buffer(buffer); + + /* If the new environment variable content is shorter than the old one, + * we need to erase the rest of the bytes + */ + + if (current<last) { + for(i=current; i<last; i++) { + nvram_write_byte(i, 0); + } + } + + return 0; /* success */ +} + diff --git a/lib/libnvram/libnvram.code b/lib/libnvram/libnvram.code new file mode 100644 index 0000000..f1fd414 --- /dev/null +++ b/lib/libnvram/libnvram.code @@ -0,0 +1,279 @@ +/****************************************************************************** + * 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 <nvram.h> + +#define STRING_INIT(str) \ + char str[255]; \ + char * str##_address; \ + int str##_length; + +#define STRING_FROM_STACK(str) \ + str##_length = TOS.u; POP; \ + str##_address = TOS.a; POP; \ + memcpy(str, str##_address, str##_length); \ + memset(str + str##_length, 0, 255 - str##_length); + +PRIM(nvram_X2d_c_X40) + unsigned int offset = TOS.u; + TOS.u=nvram_read_byte(offset); +MIRP + +PRIM(nvram_X2d_w_X40) + unsigned int offset = TOS.u; + TOS.u=nvram_read_word(offset); +MIRP + +PRIM(nvram_X2d_l_X40) + unsigned int offset = TOS.u; + TOS.u=nvram_read_dword(offset); +MIRP + +PRIM(nvram_X2d_x_X40) + unsigned int offset = TOS.u; + TOS.u=nvram_read_qword(offset); +MIRP + +PRIM(nvram_X2d_c_X21) + nvram_write_byte(TOS.u, NOS.u); + POP; POP; +MIRP + +PRIM(nvram_X2d_w_X21) + nvram_write_word(TOS.u, NOS.u); + POP; POP; +MIRP + +PRIM(nvram_X2d_l_X21) + nvram_write_dword(TOS.u, NOS.u); + POP; POP; +MIRP + +PRIM(nvram_X2d_x_X21) + nvram_write_qword(TOS.u, NOS.u); + POP; POP; +MIRP + +/* get-nvram-partition ( type -- addr len FAILED? ) */ +PRIM(get_X2d_nvram_X2d_partition) + partition_t partition; + unsigned int ptype = TOS.u; + partition = get_partition(ptype, NULL); + if(partition.len && partition.len != -1) { + TOS.u = partition.addr; + PUSH; + TOS.u = partition.len; + PUSH; + TOS.u = 0; // FALSE + } else { + TOS.u = -1; // TRUE + } +MIRP + +/* get-named-nvram-partition ( name.addr name.len -- addr len FAILED? ) */ +PRIM(get_X2d_named_X2d_nvram_X2d_partition) + STRING_INIT(name) + partition_t partition; + + STRING_FROM_STACK(name) + partition = get_partition(-1, name); + + if(partition.len && partition.len != -1) { + PUSH; + TOS.u = partition.addr; + PUSH; + TOS.u = partition.len; + PUSH; + TOS.u = 0; // FALSE + } else { + PUSH; + TOS.u = -1; // TRUE + } +MIRP + + + +/* new-nvram-partition ( type name.addr name.len len -- part.offs part.len FALSE | TRUE) */ +PRIM(new_X2d_nvram_X2d_partition) + int type, len, i, slen; + char name[12], *addr; + partition_t partition; + + len = TOS.u; POP; + slen = TOS.u; POP; + addr = (char *)TOS.u; POP; + type = TOS.u; POP; + + for (i=0; i<12; i++) { + if(slen>i) + name[i]=addr[i]; + else + name[i]=0; + } + + partition=new_nvram_partition(type, name, len); + + if(!partition.len) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = partition.addr; + PUSH; TOS.u = partition.len; + PUSH; TOS.u = 0; // FALSE + } +MIRP + +/* inrease-nvram-partition ( part.offs part.len new-len -- FALSE | TRUE ) */ +PRIM(increase_X2d_nvram_X2d_partition) + int len, ret; + partition_t partition; + + // FIXME + partition.addr = TOS.u; POP; + partition.len = TOS.u; POP; + len = TOS.u; POP; + + ret=increase_nvram_partition_size(partition, len); + + PUSH; + + if(!ret) + TOS.u=-1; // TRUE + else + TOS.u=0; // FALSE + +MIRP + +PRIM(internal_X2d_reset_X2d_nvram) + reset_nvram(); +MIRP + +PRIM(wipe_X2d_nvram) + wipe_nvram(); +MIRP + +PRIM(nvram_X2d_debug) + nvram_debug(); +MIRP + +// ( part.start part.len name.addr name.len -- var.addr var.len TRUE | false ) +PRIM(internal_X2d_get_X2d_env) + STRING_INIT(name) + partition_t part; + char *val; + + STRING_FROM_STACK(name) + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + val=get_env(part, name); + if(val) { + PUSH; TOS.a = val; + PUSH; TOS.u = strlen(val); + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } +MIRP + +// ( part.start part.len name.addr name.len val.addr val.len -- FALSE|TRUE) +PRIM(internal_X2d_add_X2d_env) + STRING_INIT(name) + STRING_INIT(value) + partition_t part; + int ret; + + STRING_FROM_STACK(value) + STRING_FROM_STACK(name) + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + ret=add_env(part, name, value); + if(ret) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } +MIRP + +// ( part.addr part.len name.addr name.len -- FALSE|TRUE) +PRIM(internal_X2d_del_X2d_env) + STRING_INIT(name) + partition_t part; + int ret; + + STRING_FROM_STACK(name); + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + ret=del_env(part, name); + if(ret) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } + +MIRP + +// internal-set-env ( part.addr part.len name.addr name.len val.addr val.len -- FALSE|TRUE) +PRIM(internal_X2d_set_X2d_env) + STRING_INIT(name) + STRING_INIT(value) + partition_t part; + int ret; + + STRING_FROM_STACK(value) + STRING_FROM_STACK(name) + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + ret=set_env(part, name, value); + if(ret) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } +MIRP + +// ( part.addr part.len -- FALSE|TRUE) +PRIM(erase_X2d_nvram_X2d_partition) + partition_t part; + int ret; + + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + ret=clear_nvram_partition(part); + if(ret) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } + +MIRP + +// ( part.addr part.len -- FALSE|TRUE) +PRIM(delete_X2d_nvram_X2d_partition) + partition_t part; + int ret; + + part.len = TOS.u; POP; + part.addr = TOS.u; POP; + + ret=delete_nvram_partition(part); + if(ret) { + PUSH; TOS.u = -1; // TRUE + } else { + PUSH; TOS.u = 0; // FALSE + } + +MIRP + + diff --git a/lib/libnvram/libnvram.in b/lib/libnvram/libnvram.in new file mode 100644 index 0000000..33ab3bc --- /dev/null +++ b/lib/libnvram/libnvram.in @@ -0,0 +1,41 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +/* NVRAM access primitives */ +cod(nvram-c@) +cod(nvram-c!) +cod(nvram-w@) +cod(nvram-w!) +cod(nvram-l@) +cod(nvram-l!) +cod(nvram-x@) +cod(nvram-x!) + +/* Generic NVRAM helpers */ +cod(internal-reset-nvram) +cod(nvram-debug) +cod(wipe-nvram) + +/* NVRAM Partition Handling */ +cod(get-nvram-partition) +cod(get-named-nvram-partition) +cod(new-nvram-partition) +cod(increase-nvram-partition) +cod(erase-nvram-partition) +cod(delete-nvram-partition) + +/* NVRAM environment access words */ +cod(internal-get-env) +cod(internal-add-env) +cod(internal-del-env) +cod(internal-set-env) + diff --git a/lib/libnvram/nvram.c b/lib/libnvram/nvram.c new file mode 100644 index 0000000..a31bb53 --- /dev/null +++ b/lib/libnvram/nvram.c @@ -0,0 +1,518 @@ +/****************************************************************************** + * 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 "cache.h" + +#include "../libc/include/stdio.h" +#include "../libc/include/string.h" +#include "../libc/include/stdlib.h" + +#include "nvram.h" + +#include <stdarg.h> +#include <string.h> +#include <southbridge.h> +#include <nvramlog.h> + +void asm_cout(long Character,long UART,long NVRAM); + +static volatile uint8_t *nvram=(volatile uint8_t *)SB_NVRAM_adr; + +/* This is extremely ugly, but still better than implementing + * another sbrk() around it. + */ +static char nvram_buffer[NVRAM_LENGTH]; +static uint8_t nvram_buffer_locked=0x00; + +/** + * producer for nvram access functions. Since these functions are + * basically all the same except for the used data types, produce + * them via the following macro to keep the code from bloating. + */ + +#define nvram_access(type,size,name) \ + type nvram_read_##name(unsigned int offset) \ + { \ + type *pos; \ + if (offset > (NVRAM_LENGTH - sizeof(type))) \ + return 0; \ + pos = (type *)(nvram+offset); \ + return ci_read_##size(pos); \ + } \ + void nvram_write_##name(unsigned int offset, type data) \ + { \ + type *pos; \ + if (offset > (NVRAM_LENGTH - sizeof(type))) \ + return; \ + pos = (type *)(nvram+offset); \ + ci_write_##size(pos, data); \ + } + +nvram_access(uint8_t, 8, byte) +nvram_access(uint16_t, 16, word) +nvram_access(uint32_t, 32, dword) +nvram_access(uint64_t, 64, qword) + +/** + * This function is a minimal abstraction for our temporary + * buffer. It should have been malloced, but since there is no + * usable malloc, we go this route. + * + * @return pointer to temporary buffer + */ + +char *get_nvram_buffer(int len) +{ + if(len>NVRAM_LENGTH) + return NULL; + + if(nvram_buffer_locked) + return NULL; + + nvram_buffer_locked = 0xff; + + return nvram_buffer; +} + +/** + * @param buffer pointer to the allocated buffer. This + * is unused, but nice in case we ever get a real malloc + */ + +void free_nvram_buffer(char *buffer __attribute__((unused))) +{ + nvram_buffer_locked = 0x00; +} + +/** + * @param fmt format string, like in printf + * @param ... variable number of arguments + */ + +int nvramlog_printf(const char* fmt, ...) +{ + char buff[256]; + int count, i; + va_list ap; + + va_start(ap, fmt); + count = vsprintf(buff, fmt, ap); + va_end(ap); + + for (i=0; i<count; i++) + asm_cout(buff[i], 0, 1); + + return count; +} + +/** + * @param offset start offset of the partition header + */ + +static uint8_t get_partition_type(int offset) +{ + return nvram_read_byte(offset); +} + +/** + * @param offset start offset of the partition header + */ + +static uint8_t get_partition_header_checksum(int offset) +{ + return nvram_read_byte(offset+1); +} + +/** + * @param offset start offset of the partition header + */ + +static uint16_t get_partition_len(int offset) +{ + return nvram_read_word(offset+2); +} + +/** + * @param offset start offset of the partition header + * @return static char array containing the partition name + * + * NOTE: If the partition name needs to be non-temporary, strdup + * and use the copy instead. + */ + +static char * get_partition_name(int offset) +{ + static char name[12]; + int i; + for (i=0; i<12; i++) + name[i]=nvram_read_byte(offset+4+i); + + // DEBUG("name: \"%s\"\n", name); + return name; +} + +static uint8_t calc_partition_header_checksum(int offset) +{ + uint16_t plainsum; + uint8_t checksum; + int i; + + plainsum = nvram_read_byte(offset); + + for (i=2; i<PARTITION_HEADER_SIZE; i++) + plainsum+=nvram_read_byte(offset+i); + + checksum=(plainsum>>8)+(plainsum&0xff); + + return checksum; +} + +static int calc_used_nvram_space(void) +{ + int walk, len; + + for (walk=0; walk<NVRAM_LENGTH;) { + if(get_partition_header_checksum(walk) != + calc_partition_header_checksum(walk)) { + /* If there's no valid entry, bail out */ + break; + } + + len=get_partition_len(walk); + // DEBUG("... part len=%x, %x\n", len, len*16); + + if(!len) { + /* If there's a partition type but no len, bail out. + * Don't bail out if type is 0. This can be used to + * find the offset of the first free byte. + */ + break; + } + + walk += len * 16; + } + DEBUG("used nvram space: %d\n", walk); + + return walk; +} + +/** + * + * @param type partition type. Set this to the partition type you are looking + * for. If there are several partitions with the same type, only + * the first partition with that type will be found. + * Set to -1 to ignore. Set to 0 to find free unpartitioned space. + * + * @param name partition name. Set this to the name of the partition you are + * looking for. If there are several partitions with the same name, + * only the first partition with that name will be found. + * Set to NULL to ignore. + * + * To disambiguate the partitions you should have a unique name if you plan to + * have several partitions of the same type. + * + */ + +partition_t get_partition(unsigned int type, char *name) +{ + partition_t ret={0,-1}; + int walk, len; + + for (walk=0; walk<NVRAM_LENGTH;) { + // DEBUG("get_partition: walk=%x\n", walk); + if(get_partition_header_checksum(walk) != + calc_partition_header_checksum(walk)) { + /* If there's no valid entry, bail out */ + break; + } + + len=get_partition_len(walk); + if(type && !len) { + /* If there's a partition type but no len, bail out. + * Don't bail out if type is 0. This can be used to + * find the offset of the first free byte. + */ + break; + } + + /* Check if either type or name or both do not match. */ + if ( (type!=(unsigned int)-1 && type != get_partition_type(walk)) || + (name && strncmp(get_partition_name(walk), name, 12)) ) { + /* We hit another partition. Continue + * at the end of this partition + */ + walk += len*16; + continue; + } + + ret.addr=walk+PARTITION_HEADER_SIZE; + ret.len=(len*16)-PARTITION_HEADER_SIZE; + break; + } + + return ret; +} + +void erase_nvram(int offset, int len) +{ + int i; + + for (i=offset; i<offset+len; i++) + nvram_write_byte(i, 0); +} + +void wipe_nvram(void) +{ + erase_nvram(0, NVRAM_LENGTH); +} + +/** + * @param partition partition structure pointing to the partition to wipe. + * @param header_only if header_only is != 0 only the partition header is + * nulled out, not the whole partition. + */ + +int wipe_partition(partition_t partition, int header_only) +{ + int pstart, len; + + pstart=partition.addr-PARTITION_HEADER_SIZE; + + len=PARTITION_HEADER_SIZE; + + if(!header_only) + len += partition.len; + + erase_nvram(pstart, len); + + return 0; +} + + +static partition_t create_nvram_partition(int type, const char *name, int len) +{ + partition_t ret = { 0, 0 }; + int offset, plen; + unsigned int i; + + plen = ALIGN(len+PARTITION_HEADER_SIZE, 16); + + DEBUG("Creating partition type=%x, name=%s, len=%d plen=%d\n", + type, name, len, plen); + + offset = calc_used_nvram_space(); + + if (NVRAM_LENGTH-(calc_used_nvram_space())<plen) { + DEBUG("Not enough free space.\n"); + return ret; + } + + DEBUG("Writing header."); + + nvram_write_byte(offset, type); + nvram_write_word(offset+2, plen/16); + + for (i=0; i<strlen(name); i++) + nvram_write_byte(offset+4+i, name[i]); + + nvram_write_byte(offset+1, calc_partition_header_checksum(offset)); + + ret.addr = offset+PARTITION_HEADER_SIZE; + ret.len = len; + + DEBUG("partition created: addr=%lx len=%lx\n", ret.addr, ret.len); + + return ret; +} + +static int create_free_partition(void) +{ + int free_space; + partition_t free_part; + + free_space = NVRAM_LENGTH - calc_used_nvram_space() - PARTITION_HEADER_SIZE; + free_part = create_nvram_partition(0x7f, "free space", free_space); + + return (free_part.addr != 0); +} + +partition_t new_nvram_partition(int type, char *name, int len) +{ + partition_t free_part, new_part = { 0, 0 }; + + /* NOTE: Assume all free space is consumed by the "free space" + * partition. This means a partition can not be increased in the middle + * of reset_nvram, which is obviously not a big loss. + */ + + free_part=get_partition(0x7f, NULL); + if( free_part.len && free_part.len != -1) + wipe_partition(free_part, 1); + + new_part = create_nvram_partition(type, name, len); + + if(new_part.len != len) { + new_part.len = 0; + new_part.addr = 0; + } + + create_free_partition(); + + return new_part; +} + +/** + * @param partition partition structure pointing to the partition to wipe. + */ + +int delete_nvram_partition(partition_t partition) +{ + int i; + partition_t free_part; + + if(!partition.len || partition.len == -1) + return 0; + + for (i=partition.addr+partition.len; i< NVRAM_LENGTH; i++) + nvram_write_byte(i - partition.len - PARTITION_HEADER_SIZE, nvram_read_byte(i)); + + erase_nvram(NVRAM_LENGTH-partition.len-PARTITION_HEADER_SIZE, + partition.len-PARTITION_HEADER_SIZE); + + free_part=get_partition(0x7f, NULL); + wipe_partition(free_part, 0); + create_free_partition(); + + return 1; +} + +int clear_nvram_partition(partition_t part) +{ + if(!part.addr) + return 0; + + erase_nvram(part.addr, part.len); + + return 1; +} + + +int increase_nvram_partition_size(partition_t partition, int newsize) +{ + partition_t free_part; + int free_offset, end_offset, i; + + /* We don't support shrinking partitions (yet) */ + if (newsize < partition.len) { + return 0; + } + + /* NOTE: Assume all free space is consumed by the "free space" + * partition. This means a partition can not be increased in the middle + * of reset_nvram, which is obviously not a big loss. + */ + + free_part=get_partition(0x7f, NULL); + + // FIXME: It could be 16 byte more. Also handle empty "free" partition. + if (free_part.len == -1 || free_part.len < newsize - partition.len ) { + return 0; + } + + free_offset=free_part.addr - PARTITION_HEADER_SIZE; // first unused byte + end_offset=partition.addr + partition.len; // last used byte of partition + 1 + + if(free_offset > end_offset) { + int j, bufferlen; + char *overlap_buffer; + + bufferlen=free_offset - end_offset; + + overlap_buffer=get_nvram_buffer(bufferlen); + if(!overlap_buffer) { + return 0; + } + + for (i=end_offset, j=0; i<free_offset; i++, j++) + overlap_buffer[j]=nvram_read_byte(i); + + /* Only wipe the header. The free space partition is empty per + * definition + */ + + wipe_partition(free_part, 1); + + for (i=partition.addr+newsize, j=0; i<(int)(partition.addr+newsize+bufferlen); i++, j++) + nvram_write_byte(i, overlap_buffer[j]); + + free_nvram_buffer(overlap_buffer); + } else { + /* Only wipe the header. */ + wipe_partition(free_part, 1); + } + + /* Clear the new partition space */ + erase_nvram(partition.addr+partition.len, newsize-partition.len); + + nvram_write_word(partition.addr - 16 + 2, newsize); + + create_free_partition(); + + return 1; +} + +static void init_cpulog_partition(partition_t cpulog) +{ + unsigned int offset=cpulog.addr; + + /* see board-xxx/include/nvramlog.h for information */ + nvram_write_word(offset+0, 0x40); // offset + nvram_write_word(offset+2, 0x00); // flags + nvram_write_dword(offset+4, 0x01); // pointer + +} + +void reset_nvram(void) +{ + partition_t cpulog0, cpulog1; + char header[12]; + + DEBUG("Erasing NVRAM\n"); + erase_nvram(0, NVRAM_LENGTH); + + DEBUG("Creating CPU log partitions\n"); + *(uint32_t *)&(header[0]) = be32_to_cpu(LLFW_LOG_BE0_NAME_PREFIX); + *(uint64_t *)&(header[4]) = be64_to_cpu(LLFW_LOG_BE0_NAME); + cpulog0=create_nvram_partition(LLFW_LOG_BE0_SIGNATURE, header, + (LLFW_LOG_BE0_LENGTH*16)-PARTITION_HEADER_SIZE); + + *(uint32_t *)&(header[0]) = be32_to_cpu(LLFW_LOG_BE1_NAME_PREFIX); + *(uint64_t *)&(header[4]) = be64_to_cpu(LLFW_LOG_BE1_NAME); + cpulog1=create_nvram_partition(LLFW_LOG_BE1_SIGNATURE, header, + (LLFW_LOG_BE1_LENGTH*16)-PARTITION_HEADER_SIZE); + + DEBUG("Initializing CPU log partitions\n"); + init_cpulog_partition(cpulog0); + init_cpulog_partition(cpulog1); + + nvramlog_printf("Creating common NVRAM partition\r\n"); + create_nvram_partition(0x70, "common", 0x01000-PARTITION_HEADER_SIZE); + + create_free_partition(); +} + +void nvram_debug(void) +{ + printf("\nNVRAM_BASE: %lx\n", (unsigned long)SB_NVRAM_adr); + printf("NVRAM_LEN: %x\n", NVRAM_LENGTH); +} + diff --git a/lib/libnvram/nvram.h b/lib/libnvram/nvram.h new file mode 100644 index 0000000..d15b85e --- /dev/null +++ b/lib/libnvram/nvram.h @@ -0,0 +1,90 @@ +/****************************************************************************** + * 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 + *****************************************************************************/ + +#ifndef __NVRAM_H +#define __NVRAM_H 1 + +/* data structures */ + +typedef struct { + unsigned long addr; + long len; +} partition_t; + +/* macros */ + +#define DEBUG(x...) +// #define DEBUG(x...) printf(x); + +#ifndef ALIGN +#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) +#endif + +#define NULL ((void *)0) + +#define PARTITION_HEADER_SIZE 16 + +/* FIXME this should be done complete and in a more prominent place */ +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#ifdef __i386__ +#define __BYTE_ORDER __LITTLE_ENDIAN +#else +#define __BYTE_ORDER __BIG_ENDIAN +#endif +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_be64(x) (x) +#define be64_to_cpu(x) (x) +#define cpu_to_be32(x) (x) +#define be32_to_cpu(x) (x) +#else +#include <byteswap.h> +#define cpu_to_be64(x) bswap_64(x) +#define be64_to_cpu(x) bswap_64(x) +#define cpu_to_be32(x) bswap_32(x) +#define be32_to_cpu(x) bswap_32(x) +#endif + +/* exported functions */ + +#define nvram_access_proto(type,name) \ + type nvram_read_##name(unsigned int offset); \ + void nvram_write_##name(unsigned int offset, type data); + +nvram_access_proto(uint8_t, byte) +nvram_access_proto(uint16_t, word) +nvram_access_proto(uint32_t, dword) +nvram_access_proto(uint64_t, qword) + +/* nvram.c */ + +char *get_nvram_buffer(int len); +void free_nvram_buffer(char *buffer); +int nvramlog_printf(const char* fmt, ...); +partition_t get_partition(unsigned int type, char *name); +void erase_nvram(int offset, int len); +int wipe_partition(partition_t partition, int header_only); +partition_t new_nvram_partition(int type, char *name, int len); +int increase_nvram_partition_size(partition_t partition, int newsize); +int clear_nvram_partition(partition_t part); +int delete_nvram_partition(partition_t part); +void reset_nvram(void); +void wipe_nvram(void); +void nvram_debug(void); + +/* envvar.c */ +char *get_env(partition_t part, char *envvar); +int add_env(partition_t part, char *envvar, char *value); +int del_env(partition_t part, char *envvar); +int set_env(partition_t part, char *envvar, char *value); + +#endif |