aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-12-01 09:51:44 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-12-01 09:51:44 +1100
commitaaad509cdca2ed5f2c92a26f5279ec0e89c4fd5f (patch)
treedfffc0d8f3d21f6736b7f09219c95e2370052d8a /lib
downloadSLOF-aaad509cdca2ed5f2c92a26f5279ec0e89c4fd5f.zip
SLOF-aaad509cdca2ed5f2c92a26f5279ec0e89c4fd5f.tar.gz
SLOF-aaad509cdca2ed5f2c92a26f5279ec0e89c4fd5f.tar.bz2
Initial import of slof-JX-1.7.0-4
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile35
-rw-r--r--lib/libbases/Makefile40
-rw-r--r--lib/libbases/libbases.code42
-rw-r--r--lib/libbases/libbases.in17
-rw-r--r--lib/libbootmsg/Makefile69
-rw-r--r--lib/libbootmsg/bootmsg.code61
-rw-r--r--lib/libbootmsg/bootmsg.in19
-rw-r--r--lib/libbootmsg/bootmsg_lvl.S199
-rw-r--r--lib/libbootmsg/libbootmsg.h21
-rw-r--r--lib/libc/Makefile61
-rw-r--r--lib/libc/README.txt49
-rw-r--r--lib/libc/ctype/Makefile.inc20
-rw-r--r--lib/libc/ctype/isdigit.c25
-rw-r--r--lib/libc/ctype/isprint.c18
-rw-r--r--lib/libc/ctype/isspace.c29
-rw-r--r--lib/libc/ctype/isxdigit.c21
-rw-r--r--lib/libc/ctype/tolower.c18
-rw-r--r--lib/libc/ctype/toupper.c21
-rw-r--r--lib/libc/getopt/Makefile.inc17
-rw-r--r--lib/libc/getopt/getopt.c470
-rw-r--r--lib/libc/include/ctype.h24
-rw-r--r--lib/libc/include/errno.h34
-rw-r--r--lib/libc/include/getopt.h37
-rw-r--r--lib/libc/include/limits.h32
-rw-r--r--lib/libc/include/stdarg.h22
-rw-r--r--lib/libc/include/stddef.h25
-rw-r--r--lib/libc/include/stdint.h28
-rw-r--r--lib/libc/include/stdio.h63
-rw-r--r--lib/libc/include/stdlib.h33
-rw-r--r--lib/libc/include/string.h36
-rw-r--r--lib/libc/include/unistd.h26
-rw-r--r--lib/libc/stdio/Makefile.inc23
-rw-r--r--lib/libc/stdio/fileno.c19
-rw-r--r--lib/libc/stdio/fprintf.c26
-rw-r--r--lib/libc/stdio/fscanf.c26
-rw-r--r--lib/libc/stdio/printf.c27
-rw-r--r--lib/libc/stdio/putc.c25
-rw-r--r--lib/libc/stdio/putchar.c21
-rw-r--r--lib/libc/stdio/puts.c28
-rw-r--r--lib/libc/stdio/scanf.c26
-rw-r--r--lib/libc/stdio/setvbuf.c28
-rw-r--r--lib/libc/stdio/sprintf.c30
-rw-r--r--lib/libc/stdio/stdchnls.c23
-rw-r--r--lib/libc/stdio/vfprintf.c27
-rw-r--r--lib/libc/stdio/vfscanf.c266
-rw-r--r--lib/libc/stdio/vsnprintf.c242
-rw-r--r--lib/libc/stdio/vsprintf.c19
-rw-r--r--lib/libc/stdio/vsscanf.c131
-rw-r--r--lib/libc/stdlib/Makefile.inc22
-rw-r--r--lib/libc/stdlib/atoi.c18
-rw-r--r--lib/libc/stdlib/atol.c18
-rw-r--r--lib/libc/stdlib/error.c15
-rw-r--r--lib/libc/stdlib/free.c26
-rw-r--r--lib/libc/stdlib/malloc.c157
-rw-r--r--lib/libc/stdlib/malloc_defs.h16
-rw-r--r--lib/libc/stdlib/memalign.c26
-rw-r--r--lib/libc/stdlib/rand.c24
-rw-r--r--lib/libc/stdlib/realloc.c40
-rw-r--r--lib/libc/stdlib/strtol.c113
-rw-r--r--lib/libc/stdlib/strtoul.c103
-rw-r--r--lib/libc/string/Makefile.inc22
-rw-r--r--lib/libc/string/memchr.c29
-rw-r--r--lib/libc/string/memcmp.c30
-rw-r--r--lib/libc/string/memcpy.c27
-rw-r--r--lib/libc/string/memmove.c42
-rw-r--r--lib/libc/string/memset.c25
-rw-r--r--lib/libc/string/strcasecmp.c28
-rw-r--r--lib/libc/string/strcat.c24
-rw-r--r--lib/libc/string/strchr.c28
-rw-r--r--lib/libc/string/strcmp.c28
-rw-r--r--lib/libc/string/strcpy.c25
-rw-r--r--lib/libc/string/strlen.c27
-rw-r--r--lib/libc/string/strncasecmp.c32
-rw-r--r--lib/libc/string/strncmp.c31
-rw-r--r--lib/libc/string/strncpy.c33
-rw-r--r--lib/libc/string/strstr.c37
-rw-r--r--lib/libc/string/strtok.c45
-rw-r--r--lib/libelf/Makefile47
-rw-r--r--lib/libelf/elf.c234
-rw-r--r--lib/libelf/libelf.code21
-rw-r--r--lib/libelf/libelf.in12
-rw-r--r--lib/libipmi/Makefile28
-rw-r--r--lib/libipmi/libipmi.code120
-rw-r--r--lib/libipmi/libipmi.h33
-rw-r--r--lib/libipmi/libipmi.in24
-rw-r--r--lib/libnvram/Makefile49
-rw-r--r--lib/libnvram/envvar.c244
-rw-r--r--lib/libnvram/libnvram.code279
-rw-r--r--lib/libnvram/libnvram.in41
-rw-r--r--lib/libnvram/nvram.c518
-rw-r--r--lib/libnvram/nvram.h90
91 files changed, 5430 insertions, 0 deletions
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 0000000..34d3c23
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,35 @@
+# *****************************************************************************
+# * 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
+# ****************************************************************************/
+
+SUBDIRS = libc libipmi libbootmsg libbases libnvram libelf
+
+
+all: subdirs
+
+.PHONY : subdirs $(SUBDIRS) clean distclean
+
+
+subdirs: $(SUBDIRS)
+
+$(SUBDIRS):
+ $(MAKE) -C $@ $(MAKEARG)
+
+# Rules for making clean:
+clean:
+ @for dir in $(SUBDIRS); do \
+ $(MAKE) -C $$dir clean || exit 1; \
+ done
+
+distclean:
+ @for dir in $(SUBDIRS); do \
+ $(MAKE) -C $$dir distclean || exit 1; \
+ done
diff --git a/lib/libbases/Makefile b/lib/libbases/Makefile
new file mode 100644
index 0000000..add4ed1
--- /dev/null
+++ b/lib/libbases/Makefile
@@ -0,0 +1,40 @@
+# *****************************************************************************
+# * Copyright (c) 2004, 2008 IBM Corporation
+# * All rights reserved.
+# * This program and the accompanying materials
+# * are made available under the terms of the BSD License
+# * which accompanies this distribution, and is available at
+# * http://www.opensource.org/licenses/bsd-license.php
+# *
+# * Contributors:
+# * IBM Corporation - initial implementation
+# ****************************************************************************/
+
+TOPCMNDIR ?= ../..
+
+include $(TOPCMNDIR)/make.rules
+
+ASFLAGS = $(FLAG) $(RELEASE) $(CPUARCHDEF) -Wa,-mregnames
+CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLBRDDIR) -I. -I../../include
+LDFLAGS = -nostdlib
+
+all:
+
+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/libbases/libbases.code b/lib/libbases/libbases.code
new file mode 100644
index 0000000..7dc941d
--- /dev/null
+++ b/lib/libbases/libbases.code
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * 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 <southbridge.h>
+
+// : get-nvram-base ( -- base )
+PRIM(get_X2d_nvram_X2d_base)
+ PUSH;
+ TOS.u = SB_NVRAM_adr;
+MIRP
+
+// : get-nvram-size ( -- size )
+PRIM(get_X2d_nvram_X2d_size)
+ PUSH;
+ TOS.u = NVRAM_LENGTH;
+MIRP
+
+// : get-flash-base ( -- base )
+PRIM(get_X2d_flash_X2d_base)
+ PUSH;
+ TOS.u = SB_FLASH_adr;
+MIRP
+
+// : get-flash-size ( -- size )
+PRIM(get_X2d_flash_X2d_size)
+ PUSH;
+ TOS.u = FLASH_LENGTH;
+MIRP
+
+// : get-mbx-base ( -- base )
+PRIM(get_X2d_mbx_X2d_base)
+ PUSH;
+ TOS.u = SB_MAILBOX_adr;
+MIRP
diff --git a/lib/libbases/libbases.in b/lib/libbases/libbases.in
new file mode 100644
index 0000000..844a55d
--- /dev/null
+++ b/lib/libbases/libbases.in
@@ -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
+ *****************************************************************************/
+
+cod(get-nvram-base)
+cod(get-nvram-size)
+cod(get-flash-base)
+cod(get-flash-size)
+cod(get-mbx-base)
diff --git a/lib/libbootmsg/Makefile b/lib/libbootmsg/Makefile
new file mode 100644
index 0000000..6804b8d
--- /dev/null
+++ b/lib/libbootmsg/Makefile
@@ -0,0 +1,69 @@
+# *****************************************************************************
+# * 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
+# ****************************************************************************/
+
+TOPCMNDIR ?= ../..
+
+ASFLAGS = $(FLAG) $(RELEASE) $(CPUARCHDEF) -Wa,-mregnames
+CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLBRDDIR) -I. -I../../include
+LDFLAGS = -nostdlib
+
+TARGET = ../libbootmsg.a
+
+
+all: $(TARGET)
+
+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)
+
+$(TARGET): $(OBJS)
+ $(AR) -rc $@ $(OBJS)
+ $(RANLIB) $@
+
+%.o: %.S
+ $(CC) $(CPPFLAGS) $(ASFLAGS) -c $< -o $@
+
+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
+ $(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
new file mode 100644
index 0000000..ae370af
--- /dev/null
+++ b/lib/libbootmsg/bootmsg.code
@@ -0,0 +1,61 @@
+/******************************************************************************
+ * 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 <libbootmsg.h>
+
+// : cp ( cp-id -- )
+PRIM(bootmsg_X2d_cp)
+ int cpid = TOS.n; POP;
+ bootmsg_cp(cpid);
+MIRP
+
+// : bootmsg-warning ( cp-id lvl pstr -- )
+PRIM(bootmsg_X2d_warning)
+ char* str = TOS.a; POP;
+ short lvl = TOS.n; POP;
+ short cpid = TOS.n; POP;
+ bootmsg_warning(cpid, (const char*)str, lvl);
+MIRP
+
+// : bootmsg-error ( cp-id pstr -- )
+PRIM(bootmsg_X2d_error)
+ char* str = TOS.a; POP;
+ short cpid = TOS.n; POP;
+ bootmsg_error(cpid, (const char*)str);
+MIRP
+
+// : bootmsg-debugcp ( cp-id lvl pstr -- )
+PRIM(bootmsg_X2d_debugcp)
+ char* str = TOS.a; POP;
+ short lvl = TOS.n; POP;
+ short cpid = TOS.n; POP;
+ bootmsg_debugcp(cpid, (const char*)str, lvl);
+MIRP
+
+// : bootmsg-setlevel ( area lvl -- )
+PRIM(bootmsg_X2d_setlevel)
+ char lvl = TOS.n; POP;
+ short area = TOS.n; POP;
+ bootmsg_setlevel(area, lvl);
+MIRP
+
+// : 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
new file mode 100644
index 0000000..73e01e3
--- /dev/null
+++ b/lib/libbootmsg/bootmsg.in
@@ -0,0 +1,19 @@
+/******************************************************************************
+ * 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
+ *****************************************************************************/
+
+cod(bootmsg-cp)
+cod(bootmsg-warning)
+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
new file mode 100644
index 0000000..04ace12
--- /dev/null
+++ b/lib/libbootmsg/bootmsg_lvl.S
@@ -0,0 +1,199 @@
+/******************************************************************************
+ * 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
+ *****************************************************************************/
+#define _ASM_
+#include "macros.h"
+#include "southbridge.h"
+#include "nvramlog.h"
+
+#define bootmsg_area_size 128
+
+ .text
+ .align 3
+
+// Declare the warning level for all 128 possibilities of AC/pCKG kombinations
+ WRNG_LVL:
+ .rept bootmsg_area_size
+ .byte 0x0
+ .endr
+
+
+//*****************************************************************************
+// Check UserWarningLevel against SystemWarningLevel
+// input : r3=cp-id, r5=level
+// change: r6,r7
+// output: CR0 ( compared user vs system level )
+// example:
+// bl GET_WRNG_LVL
+// ble print_warning
+// bgt do_not_print_warning
+ENTRY(GET_WRNG_LVL)
+ mflr r7 // save linkage register
+ bl 0f // get current
+0: mflr r6 // Instruction Address
+ mtlr r7 // restore linkage register
+ addi r6,r6,WRNG_LVL-0b // calc addr of WRNG_LVL array
+ rldic r7,r3,56,57 // calc index into array
+ lbzux r7,r6,r7 // read the warning level
+ cmpw r5,r7 // and compare it
+ blr
+
+//*****************************************************************************
+// Print CheckPoint
+// input : r3=cp-id
+// change: r3, r4, r5, r6, r7, r11
+// output: none
+ENTRY(bootmsg_cp)
+ mflr r11
+ mr r9, r3 // save checkpoint ID
+ li r3, 'C'
+ bl io_putchar // print character
+ mr r3, r9
+ bl io_printhex16 // print checkpoint ID
+ .rept 5
+ li r3,'\b'
+ bl io_putchar // print backspaces
+ .endr
+ mtlr r11
+ blr
+
+//*****************************************************************************
+// Print a general BootMessage
+// input : r3=cp-id, r4=string, r5=char (type C,W,E)
+// change: r3,r4,r5,r6,r7,r9,r10,r11,r12
+// output: none
+ENTRY(print_msg)
+ mflr r11 // Save linkage register
+ mr r9, r3 // Save ID
+ mr r10, r4 // Save ptr to string
+ mr r12, r5 // Save type (char [CWE])
+ li r3, '\n' // make it a new line
+ bl io_putchar
+ li r3, '\r'
+ bl io_putchar
+ mr r3, r12 // restore type
+ bl io_putchar // print character
+ mr r3, r9 // restore ID
+ bl io_printhex16 // print checkpoint ID
+ li r3, ' ' // print a space
+ bl io_putchar
+ mr r3, r10 // restore ptr to string
+ bl io_print // print message
+ li r3, '\n' // add a new line
+ bl io_putchar
+ li r3, '\r'
+ bl io_putchar
+ mtlr r11 // restore linkage register
+ blr
+
+//*****************************************************************************
+// Print an Error Boot Message
+// input : r3=cp-id, r4=string-ptr
+// change : r3,r4,r5,r6,r7,r9,r10,r11,r12
+// output : none
+ENTRY(bootmsg_error)
+ li r5, 'E' // E is for Error
+ b print_msg // and print this message
+
+//*****************************************************************************
+// Print a Warning Boot Message
+// input : r3=cp-id, r4=string-ptr, r5=level
+// change : r3,r4,r5,r6,r7,r9,r10,r11,r12
+// output : none
+ENTRY(bootmsg_warning)
+ mflr r11 // save linkage register
+ bl GET_WRNG_LVL // check UserLevel against SystemLevel
+ mtlr r11 // restore linkage register
+ li r5, 'W' // 'W' is for Warning
+ ble print_msg // if UserLevel<=SystemLevel print and return
+ blr // else return
+
+//*****************************************************************************
+// Print a Debug Checkpoint
+// input : r3=cp-id, r4=string-ptr, r5=level
+// change : r3,r4,r5,r6,r7,r9,r10,r11,r12
+// output : none
+// r3=cp-id, r4=string, r5=level
+ENTRY(bootmsg_debugcp)
+ mflr r11 // save linkage register
+ addi r5,r5,0x20 // add checkpoint offset
+ bl GET_WRNG_LVL // check UserLevel against SystemLevel
+ mtlr r11 // restore linkage register
+ li r5, 'D' // 'D' is for Debug CheckPoint
+ 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
+ bl WarningMsg // calc current IA
+ WarningMsg:
+ mflr r6 // get current IA
+ addi r6,r6,WRNG_LVL-WarningMsg
+ andi. r3, r3, 0x7F
+ add r6,r3,r6 // address |
+ stb r4,0(r6) // store level |_ stwbrx r4,r3,r6
+ LOAD64(r6, SB_NVRAM_FWONLY_adr + 8 )
+ add r6,r6,r3
+ stb r4,0(r6)
+ mtlr r5
+ blr
+
+ENTRY(bootmsg_nvupdate)
+ mflr r10
+ LOAD64(r3, SB_NVRAM_FWONLY_adr)
+ lwz r4, 0(r3)
+ cmpwi r4, 0x424E // find bootmsg area header
+ bne 0f
+
+ LOAD64(r5, bootmsg_area_size/8)
+ mtctr r5
+ bl WngMsg
+ WngMsg:
+ mflr r5
+ addi r5,r5,WRNG_LVL-WngMsg-8
+
+1:
+ ldu r4, 8(r3)
+ stdu r4, 8(r5)
+ bdnz+ 1b
+ b 2f
+
+0:
+ LOAD64(r5, bootmsg_area_size)
+ mtctr r5
+ li r4, 0x424E // clear bootmsg log area
+ stw r4, 0(r3)
+ li r4, 0
+
+1: stdu r4, 8(r3)
+ bdnz+ 1b
+
+2: // the end
+ mtlr r10
+ blr
diff --git a/lib/libbootmsg/libbootmsg.h b/lib/libbootmsg/libbootmsg.h
new file mode 100644
index 0000000..9d0bd15
--- /dev/null
+++ b/lib/libbootmsg/libbootmsg.h
@@ -0,0 +1,21 @@
+/******************************************************************************
+ * 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 _LIBBOOTMSG_H
+#define _LIBBOOTMSG_H
+void bootmsg_cp(short p);
+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);
+int bootmsg_checklevel(short p, short level);
+void *bootmsg_nvupdate(void);
+#endif /* _LIBBOOTMSG_H */
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
new file mode 100644
index 0000000..0c762ec
--- /dev/null
+++ b/lib/libc/Makefile
@@ -0,0 +1,61 @@
+# *****************************************************************************
+# * 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
+# ****************************************************************************/
+
+TOPCMNDIR ?= ../..
+
+LIBCCMNDIR = $(shell pwd)
+STRINGCMNDIR = $(LIBCCMNDIR)/string
+CTYPECMNDIR = $(LIBCCMNDIR)/ctype
+STDLIBCMNDIR = $(LIBCCMNDIR)/stdlib
+STDIOCMNDIR = $(LIBCCMNDIR)/stdio
+GETOPTCMNDIR = $(LIBCCMNDIR)/getopt
+
+include $(TOPCMNDIR)/make.rules
+
+
+CPPFLAGS = -I$(LIBCCMNDIR)/include
+LDFLAGS= -nostdlib
+
+TARGET = ../libc.a
+
+
+all: $(TARGET)
+
+# Use the following target to build a native version of the lib
+# (for example for debugging purposes):
+native:
+ $(MAKE) CROSS="" CC=$(HOSTCC) NATIVEBUILD=1
+
+
+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) $(GETOPT_OBJS)
+
+ifneq ($(NATIVEBUILD),1)
+# These parts of the libc use assembler, so they can only be compiled when
+# we are _not_ building a native version.
+endif
+
+
+$(TARGET): $(OBJS)
+ $(AR) -rc $@ $(OBJS)
+ $(RANLIB) $@
+
+
+clean:
+ $(RM) $(TARGET) $(OBJS)
+
+distclean: clean
diff --git a/lib/libc/README.txt b/lib/libc/README.txt
new file mode 100644
index 0000000..eaafdf4
--- /dev/null
+++ b/lib/libc/README.txt
@@ -0,0 +1,49 @@
+
+ Standard C library for the SLOF firmware project
+ ================================================
+
+To use this library, link your target against the "libc.a" archive.
+
+However, there are some prerequisites before you can use certain parts of the
+library:
+
+1) If you want to use malloc() and the like, you have to supply an implemen-
+ tation of sbrk() in your own code. malloc() uses sbrk() to get new, free
+ memory regions.
+
+ Prototype: void *sbrk(int incr);
+ Description: sbrk() increments the available data space by incr bytes and
+ returns a pointer to the start of the new area.
+
+ See the man-page of sbrk for details about this function.
+
+2) Before you can use the stdio output functions like printf(), puts() and the
+ like, you have to provide a standard write() function in your code.
+ printf() and the like use write() to print out the strings to the standard
+ output.
+
+ Prototype: ssize_t write(int fd, const void *buf, size_t cnt);
+ Description: Write cnt byte from the buffer buf to the stream associated
+ with the file descriptor fd.
+
+ The stdio functions will print their output to the stdout channel which is
+ assigned with the file descriptor 1 by default. Note that the stdio
+ functions will not use open() before calling write(), so if the stdout
+ cannel needs to be opened first, you should do that in your start-up code
+ before using the libc functions for the first time.
+
+3) Before you can use the stdio input functions like scanf() and the
+ like, you have to provide a standard read() function in your code.
+ scanf() and the like use read() to get the characters from the standard
+ input.
+
+ Prototype: ssize_t read(int fd, void *buf, size_t cnt);
+ Description: Read cnt byte from the stream associated with the file
+ descriptor fd and put them into the buffer buf.
+
+ The stdio functions will get their input from the stdin channel which is
+ assigned with the file descriptor 0 by default. Note that the stdio
+ functions will not use open() before calling read(), so if the stdin
+ cannel needs to be opened first, you should do that in your start-up code
+ before using the libc functions for the first time.
+
diff --git a/lib/libc/ctype/Makefile.inc b/lib/libc/ctype/Makefile.inc
new file mode 100644
index 0000000..25513a9
--- /dev/null
+++ b/lib/libc/ctype/Makefile.inc
@@ -0,0 +1,20 @@
+# *****************************************************************************
+# * 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
+# ****************************************************************************/
+
+
+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)
+
+%.o : $(CTYPECMNDIR)/%.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
diff --git a/lib/libc/ctype/isdigit.c b/lib/libc/ctype/isdigit.c
new file mode 100644
index 0000000..62d08a1
--- /dev/null
+++ b/lib/libc/ctype/isdigit.c
@@ -0,0 +1,25 @@
+/******************************************************************************
+ * 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 isdigit(int ch)
+{
+ switch (ch) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ return 1;
+
+ default:
+ return 0;
+ }
+}
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
new file mode 100644
index 0000000..5123019
--- /dev/null
+++ b/lib/libc/ctype/isspace.c
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * 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 isspace(int ch)
+{
+ switch (ch) {
+ case ' ':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '\v':
+ return 1;
+
+ default:
+ return 0;
+ }
+}
diff --git a/lib/libc/ctype/isxdigit.c b/lib/libc/ctype/isxdigit.c
new file mode 100644
index 0000000..9d323f3
--- /dev/null
+++ b/lib/libc/ctype/isxdigit.c
@@ -0,0 +1,21 @@
+/******************************************************************************
+ * 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 isxdigit(int ch)
+{
+ return (
+ (ch >= '0' && ch <= '9') |
+ (ch >= 'A' && ch <= 'F') |
+ (ch >= 'a' && ch <= 'f') );
+}
diff --git a/lib/libc/ctype/tolower.c b/lib/libc/ctype/tolower.c
new file mode 100644
index 0000000..f775e90
--- /dev/null
+++ b/lib/libc/ctype/tolower.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 tolower(int c)
+{
+ return (((c >= 'A') && (c <= 'Z')) ? (c - 'A' + 'a' ) : c);
+}
diff --git a/lib/libc/ctype/toupper.c b/lib/libc/ctype/toupper.c
new file mode 100644
index 0000000..9bcee52
--- /dev/null
+++ b/lib/libc/ctype/toupper.c
@@ -0,0 +1,21 @@
+/******************************************************************************
+ * 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 toupper (int cha)
+{
+ if((cha >= 'a') && (cha <= 'z'))
+ return(cha - 'a' + 'A');
+ return(cha);
+}
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
new file mode 100644
index 0000000..9051a75
--- /dev/null
+++ b/lib/libc/include/ctype.h
@@ -0,0 +1,24 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#ifndef _CTYPE_H
+#define _CTYPE_H
+
+int isdigit(int c);
+int isxdigit(int c);
+int isprint(int c);
+int isspace(int c);
+
+int tolower(int c);
+int toupper(int c);
+
+#endif
diff --git a/lib/libc/include/errno.h b/lib/libc/include/errno.h
new file mode 100644
index 0000000..d585934
--- /dev/null
+++ b/lib/libc/include/errno.h
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * 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 _ERRNO_H
+#define _ERRNO_H
+
+extern int errno;
+
+/*
+ * Error number definitions
+ */
+#define EPERM 1 /* not permitted */
+#define ENOENT 2 /* file or directory not found */
+#define EIO 5 /* input/output error */
+#define ENOMEM 12 /* not enough space */
+#define EACCES 13 /* permission denied */
+#define EFAULT 14 /* bad address */
+#define EBUSY 16 /* resource busy */
+#define EEXIST 17 /* file already exists */
+#define ENODEV 19 /* device not found */
+#define EINVAL 22 /* invalid argument */
+#define EDOM 33 /* math argument out of domain of func */
+#define ERANGE 34 /* math result not representable */
+
+#endif
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
new file mode 100644
index 0000000..4726835
--- /dev/null
+++ b/lib/libc/include/limits.h
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * 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 _LIMITS_H
+#define _LIMITS_H
+
+#define UCHAR_MAX 255
+#define SCHAR_MAX 127
+#define SCHAR_MIN (-128)
+
+#define USHRT_MAX 65535
+#define SHRT_MAX 32767
+#define SHRT_MIN (-32768)
+
+#define UINT_MAX (4294967295U)
+#define INT_MAX 2147483647
+#define INT_MIN (-2147483648)
+
+#define ULONG_MAX ((unsigned long)-1L)
+#define LONG_MAX (ULONG_MAX/2)
+#define LONG_MIN ((-LONG_MAX)-1)
+
+#endif
diff --git a/lib/libc/include/stdarg.h b/lib/libc/include/stdarg.h
new file mode 100644
index 0000000..d3d12f7
--- /dev/null
+++ b/lib/libc/include/stdarg.h
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#ifndef _STDARG_H
+#define _STDARG_H
+
+typedef __builtin_va_list va_list;
+
+#define va_start(v,l) __builtin_va_start(v,l)
+#define va_arg(v,l) __builtin_va_arg(v,l)
+#define va_end(v) __builtin_va_end(v)
+
+#endif
diff --git a/lib/libc/include/stddef.h b/lib/libc/include/stddef.h
new file mode 100644
index 0000000..ba2d960
--- /dev/null
+++ b/lib/libc/include/stddef.h
@@ -0,0 +1,25 @@
+/******************************************************************************
+ * 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 _STDDEF_H
+#define _STDDEF_H
+
+
+#define NULL ((void *)0)
+
+
+typedef unsigned int size_t;
+
+
+#endif
+
+
diff --git a/lib/libc/include/stdint.h b/lib/libc/include/stdint.h
new file mode 100644
index 0000000..518a723
--- /dev/null
+++ b/lib/libc/include/stdint.h
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * 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 _STDINT_H
+#define _STDINT_H
+
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+
+typedef unsigned short uint16_t;
+typedef signed short int16_t;
+
+typedef unsigned int uint32_t;
+typedef signed int int32_t;
+
+typedef unsigned long long uint64_t;
+typedef signed long long int64_t;
+
+#endif
diff --git a/lib/libc/include/stdio.h b/lib/libc/include/stdio.h
new file mode 100644
index 0000000..84cddea
--- /dev/null
+++ b/lib/libc/include/stdio.h
@@ -0,0 +1,63 @@
+/******************************************************************************
+ * 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 _STDIO_H
+#define _STDIO_H
+
+#include <stdarg.h>
+#include "stddef.h"
+
+#define EOF (-1)
+
+#define _IONBF 0
+#define _IOLBF 1
+#define _IOFBF 2
+#define BUFSIZ 80
+
+typedef struct {
+ int fd;
+ int mode;
+ int pos;
+ char *buf;
+ int bufsiz;
+} FILE;
+
+extern FILE stdin_data;
+extern FILE stdout_data;
+extern FILE stderr_data;
+
+#define stdin (&stdin_data)
+#define stdout (&stdout_data)
+#define stderr (&stderr_data)
+
+int fileno(FILE *stream);
+int printf(const char *format, ...) __attribute__((format (printf, 1, 2)));
+int fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3)));
+int sprintf(char *str, const char *format, ...) __attribute__((format (printf, 2, 3)));
+int vfprintf(FILE *stream, const char *format, va_list);
+int vsprintf(char *str, const char *format, va_list);
+int vsnprintf(char *str, size_t size, const char *format, va_list);
+void setbuf(FILE *stream, char *buf);
+int setvbuf(FILE *stream, char *buf, int mode , size_t size);
+
+int putc(int ch, FILE *stream);
+int putchar(int ch);
+int puts(char *str);
+
+int scanf(const char *format, ...) __attribute__((format (scanf, 1, 2)));
+int fscanf(FILE *stream, const char *format, ...) __attribute__((format (scanf, 2, 3)));
+int vfscanf(FILE *stream, const char *format, va_list);
+int vsscanf(const char *str, const char *format, va_list);
+int getc(FILE *stream);
+int getchar(void);
+
+#endif
diff --git a/lib/libc/include/stdlib.h b/lib/libc/include/stdlib.h
new file mode 100644
index 0000000..dff57f5
--- /dev/null
+++ b/lib/libc/include/stdlib.h
@@ -0,0 +1,33 @@
+/******************************************************************************
+ * 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 _STDLIB_H
+#define _STDLIB_H
+
+#include "stddef.h"
+
+#define RAND_MAX 32767
+
+
+void *malloc(size_t size);
+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);
+
+int rand(void);
+
+#endif
diff --git a/lib/libc/include/string.h b/lib/libc/include/string.h
new file mode 100644
index 0000000..ebc7568
--- /dev/null
+++ b/lib/libc/include/string.h
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * 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 _STRING_H
+#define _STRING_H
+
+#include "stddef.h"
+
+char *strcpy(char *dest, const char *src);
+char *strncpy(char *dest, const char *src, size_t n);
+char *strcat(char *dest, const char *src);
+int strcmp(const char *s1, const char *s2);
+int strncmp(const char *s1, const char *s2, size_t n);
+int strcasecmp(const char *s1, const char *s2);
+int strncasecmp(const char *s1, const char *s2, size_t n);
+char *strchr(const char *s, int c);
+char *strrchr(const char *s, int c);
+size_t strlen(const char *s);
+char *strstr(const char *hay, const char *needle);
+
+void *memset(void *s, int c, size_t n);
+void *memchr(const void *s, int c, size_t n);
+void *memcpy(void *dest, const void *src, size_t n);
+void *memmove(void *dest, const void *src, size_t n);
+int memcmp(const void *s1, const void *s2, size_t n);
+
+#endif
diff --git a/lib/libc/include/unistd.h b/lib/libc/include/unistd.h
new file mode 100644
index 0000000..f1b1c62
--- /dev/null
+++ b/lib/libc/include/unistd.h
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#ifndef _UNISTD_H
+#define _UNISTD_H
+
+typedef long ssize_t;
+
+extern int open(const char *name, int flags);
+extern int close(int fd);
+extern ssize_t read(int fd, void *buf, size_t count);
+extern ssize_t write(int fd, const void *buf, size_t count);
+extern ssize_t lseek(int fd, long offset, int whence);
+
+extern void *sbrk(int increment);
+
+#endif
diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc
new file mode 100644
index 0000000..ac5302d
--- /dev/null
+++ b/lib/libc/stdio/Makefile.inc
@@ -0,0 +1,23 @@
+# *****************************************************************************
+# * 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
+# ****************************************************************************/
+
+
+STDIO_SRC_C = fscanf.c sprintf.c vfprintf.c vsnprintf.c vsprintf.c fprintf.c \
+ printf.c setvbuf.c putc.c puts.c putchar.c scanf.c stdchnls.c \
+ vfscanf.c vsscanf.c fileno.c
+
+STDIO_SRC_ASM =
+STDIO_SRCS = $(STDIO_SRC_C:%=$(STDIOCMNDIR)/%) $(STDIO_SRC_ASM:%=$(STDIOCMNDIR)/%)
+STDIO_OBJS = $(STDIO_SRC_C:%.c=%.o) $(STDIO_SRC_ASM:%.S=%.o)
+
+%.o : $(STDIOCMNDIR)/%.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
diff --git a/lib/libc/stdio/fileno.c b/lib/libc/stdio/fileno.c
new file mode 100644
index 0000000..6e23951
--- /dev/null
+++ b/lib/libc/stdio/fileno.c
@@ -0,0 +1,19 @@
+/******************************************************************************
+ * 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 <stdio.h>
+
+int
+fileno(FILE *stream)
+{
+ return stream->fd;
+}
diff --git a/lib/libc/stdio/fprintf.c b/lib/libc/stdio/fprintf.c
new file mode 100644
index 0000000..866df39
--- /dev/null
+++ b/lib/libc/stdio/fprintf.c
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include "stdio.h"
+
+
+int fprintf(FILE *stream, const char* fmt, ...)
+{
+ int count;
+ va_list ap;
+
+ va_start(ap, fmt);
+ count = vfprintf(stream, fmt, ap);
+ va_end(ap);
+
+ return count;
+}
diff --git a/lib/libc/stdio/fscanf.c b/lib/libc/stdio/fscanf.c
new file mode 100644
index 0000000..321b163
--- /dev/null
+++ b/lib/libc/stdio/fscanf.c
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include <stdio.h>
+
+int
+fscanf(FILE *stream, const char *fmt, ...)
+{
+ int count;
+ va_list ap;
+
+ va_start(ap, fmt);
+ count = vfscanf(stream, fmt, ap);
+ va_end(ap);
+
+ return count;
+}
diff --git a/lib/libc/stdio/printf.c b/lib/libc/stdio/printf.c
new file mode 100644
index 0000000..01f4592
--- /dev/null
+++ b/lib/libc/stdio/printf.c
@@ -0,0 +1,27 @@
+/******************************************************************************
+ * 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 "stdio.h"
+
+
+int printf(const char* fmt, ...)
+{
+ int count;
+ va_list ap;
+
+ va_start(ap, fmt);
+ count = vfprintf(stdout, fmt, ap);
+ va_end(ap);
+
+ return count;
+}
+
diff --git a/lib/libc/stdio/putc.c b/lib/libc/stdio/putc.c
new file mode 100644
index 0000000..230e9d1
--- /dev/null
+++ b/lib/libc/stdio/putc.c
@@ -0,0 +1,25 @@
+/******************************************************************************
+ * 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 "stdio.h"
+#include "unistd.h"
+
+int
+putc(int ch, FILE *stream)
+{
+ unsigned char outchar = ch;
+
+ if (write(stream->fd, &outchar, 1) == 1)
+ return outchar;
+ else
+ return EOF;
+}
diff --git a/lib/libc/stdio/putchar.c b/lib/libc/stdio/putchar.c
new file mode 100644
index 0000000..5c750d9
--- /dev/null
+++ b/lib/libc/stdio/putchar.c
@@ -0,0 +1,21 @@
+/******************************************************************************
+ * 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 "stdio.h"
+
+
+int
+putchar(int ch)
+{
+ return putc(ch, stdout);
+}
diff --git a/lib/libc/stdio/puts.c b/lib/libc/stdio/puts.c
new file mode 100644
index 0000000..3f48dbf
--- /dev/null
+++ b/lib/libc/stdio/puts.c
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * 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 "stdio.h"
+#include "string.h"
+#include "unistd.h"
+
+
+int
+puts(char *str)
+{
+ int ret;
+
+ ret = write(stdout->fd, str, strlen(str));
+ write(stdout->fd, "\r\n", 2);
+
+ return ret;
+}
diff --git a/lib/libc/stdio/scanf.c b/lib/libc/stdio/scanf.c
new file mode 100644
index 0000000..96b6399
--- /dev/null
+++ b/lib/libc/stdio/scanf.c
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include <stdio.h>
+
+int
+scanf(const char *fmt, ...)
+{
+ int count;
+ va_list ap;
+
+ va_start(ap, fmt);
+ count = vfscanf(stdin, fmt, ap);
+ va_end(ap);
+
+ return count;
+}
diff --git a/lib/libc/stdio/setvbuf.c b/lib/libc/stdio/setvbuf.c
new file mode 100644
index 0000000..9b62dd8
--- /dev/null
+++ b/lib/libc/stdio/setvbuf.c
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * 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 <stdio.h>
+
+int setvbuf(FILE *stream, char *buf, int mode , size_t size)
+{
+ if (mode != _IONBF && mode != _IOLBF && mode != _IOFBF)
+ return -1;
+ stream->buf = buf;
+ stream->mode = mode;
+ stream->bufsiz = size;
+ return 0;
+}
+
+void setbuf(FILE *stream, char *buf)
+{
+ setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
+}
diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c
new file mode 100644
index 0000000..9c4540e
--- /dev/null
+++ b/lib/libc/stdio/sprintf.c
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * 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 <stdio.h>
+
+
+int sprintf(char *buff, const char *format, ...)
+{
+ va_list ar;
+ int count;
+
+ if ((buff==NULL) || (format==NULL))
+ return(-1);
+
+ va_start(ar, format);
+ count = vsprintf(buff, format, ar);
+ va_end(ar);
+
+ return(count);
+}
+
diff --git a/lib/libc/stdio/stdchnls.c b/lib/libc/stdio/stdchnls.c
new file mode 100644
index 0000000..41ed958
--- /dev/null
+++ b/lib/libc/stdio/stdchnls.c
@@ -0,0 +1,23 @@
+/******************************************************************************
+ * 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 "stdio.h"
+
+static char stdin_buffer[BUFSIZ], stdout_buffer[BUFSIZ];
+
+FILE stdin_data = { .fd = 0, .mode = _IOLBF, .pos = 0,
+ .buf = stdin_buffer, .bufsiz = BUFSIZ };
+FILE stdout_data = { .fd = 1, .mode = _IOLBF, .pos = 0,
+ .buf = stdout_buffer, .bufsiz = BUFSIZ };
+FILE stderr_data = { .fd = 2, .mode = _IONBF, .pos = 0,
+ .buf = NULL, .bufsiz = 0 };
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
new file mode 100644
index 0000000..765feea
--- /dev/null
+++ b/lib/libc/stdio/vfprintf.c
@@ -0,0 +1,27 @@
+/******************************************************************************
+ * 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 "stdio.h"
+#include "unistd.h"
+
+
+int vfprintf(FILE *stream, const char *fmt, va_list ap)
+{
+ int count;
+ char buffer[320];
+
+ count = vsnprintf(buffer, sizeof(buffer), fmt, ap);
+ write(stream->fd, buffer, count);
+
+ return count;
+}
+
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
new file mode 100644
index 0000000..4ddd210
--- /dev/null
+++ b/lib/libc/stdio/vfscanf.c
@@ -0,0 +1,266 @@
+/******************************************************************************
+ * 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"
+#include "ctype.h"
+#include "stdlib.h"
+#include "stdio.h"
+#include "unistd.h"
+
+
+static int
+_getc(FILE * stream)
+{
+ int count;
+ char c;
+
+ if (stream->mode == _IONBF || stream->buf == NULL) {
+ 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') {
+ count = read(stream->fd, stream->buf, BUFSIZ);
+ if (count < 0)
+ count = 0;
+ if (count < BUFSIZ)
+ stream->buf[count] = '\0';
+ stream->pos = 0;
+ }
+
+ return stream->buf[stream->pos++];
+}
+
+static void
+_ungetc(int ch, FILE * stream)
+{
+ if (stream->mode != _IONBF && stream->pos > 0)
+ stream->pos--;
+}
+
+static int
+_is_voidage(int ch)
+{
+ if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\0')
+ return 1;
+ else
+ return 0;
+}
+
+
+static int
+_scanf(FILE * stream, const char *fmt, va_list * ap)
+{
+ int i = 0;
+ int length = 0;
+
+ fmt++;
+
+ 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++;
+ }
+ }
+ /* 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);
+
+ 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);
+
+ 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++;
+ }
+ }
+ /* _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, 8);
+ break;
+ case 'c':
+ ch = _getc(stream);
+ while (_is_voidage(ch))
+ ch = _getc(stream);
+
+ *(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);
+
+ strcpy(va_arg(*ap, char *), tbuf);
+ break;
+ default:
+ if (*fmt >= '0' && *fmt <= '9')
+ length += *fmt - '0';
+ break;
+ }
+ fmt++;
+ }
+
+ return 1;
+}
+
+
+
+int
+vfscanf(FILE * stream, const char *fmt, va_list ap)
+{
+ int args = 0;
+
+ while (*fmt != '\0') {
+
+ if (*fmt == '%') {
+
+ char formstr[20];
+ 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'));
+ formstr[i++] = *fmt;
+ formstr[i] = '\0';
+ if (*fmt != '%') {
+ if (_scanf(stream, formstr, &ap) <= 0)
+ return args;
+ else
+ args++;
+ }
+
+ }
+
+ fmt++;
+
+ }
+
+ return args;
+}
+
+int
+getc(FILE * stream)
+{
+ return _getc(stream);
+}
+
+int
+getchar(void)
+{
+ return _getc(stdin);
+}
diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c
new file mode 100644
index 0000000..e78fb3d
--- /dev/null
+++ b/lib/libc/stdio/vsnprintf.c
@@ -0,0 +1,242 @@
+/******************************************************************************
+ * 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 "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+
+const static unsigned long long convert[] = {
+ 0x0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFFFFULL, 0xFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
+};
+
+
+
+static int
+print_itoa(char **buffer,unsigned long value, unsigned short int base)
+{
+ const char zeichen[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+ static char sign = 0;
+
+ if(base <= 2 || base > 16)
+ return 0;
+
+ if(value < 0) {
+ sign = 1;
+ value *= -1;
+ }
+
+ if(value < base) {
+ if(sign) {
+ **buffer = '-';
+ *buffer += 1;
+ sign = 0;
+ }
+ **buffer = zeichen[value];
+ *buffer += 1;
+ } else {
+ print_itoa(buffer, value / base, base);
+ **buffer = zeichen[(value % base)];
+ *buffer += 1;
+ }
+
+ return 1;
+}
+
+
+static unsigned int
+print_intlen(unsigned long value, unsigned short int base)
+{
+ int i = 0;
+
+ while(value > 0) {
+ value /= base;
+ i++;
+ }
+ if(i == 0) i = 1;
+ return i;
+}
+
+
+static int
+print_fill(char **buffer, char *sizec, unsigned long size, unsigned short int base, char c, int optlen)
+{
+ int i, sizei, len;
+
+ sizei = strtoul(sizec, NULL, 10);
+ len = print_intlen(size, base) + optlen;
+ if(sizei > len) {
+ for(i = 0; i < (sizei - len); i++) {
+ **buffer = c;
+ *buffer += 1;
+ }
+ }
+
+ return 0;
+}
+
+
+static int
+print_format(char **buffer, const char *format, void *var)
+{
+ unsigned long start;
+ unsigned int i = 0, sizei = 0, len = 0, length_mod = sizeof(int);
+ unsigned long value = 0;
+ unsigned long signBit;
+ char *form, sizec[32];
+ char sign = ' ';
+
+ form = (char *) format;
+ start = (unsigned long) *buffer;
+
+ form++;
+ if(*form == '0' || *form == '.') {
+ sign = '0';
+ form++;
+ }
+
+ while(*form != '\0') {
+ switch(*form) {
+ case 'u':
+ case 'd':
+ case 'i':
+ sizec[i] = '\0';
+ value = (unsigned long) var;
+ signBit = 0x1ULL << (length_mod * 8 - 1);
+ if (signBit & value) {
+ **buffer = '-';
+ *buffer += 1;
+ value = (-(unsigned long)value) & convert[length_mod];
+ }
+ print_fill(buffer, sizec, value, 10, sign, 0);
+ print_itoa(buffer, value, 10);
+ break;
+ case 'X':
+ case 'x':
+ sizec[i] = '\0';
+ value = (unsigned long) var & convert[length_mod];
+ print_fill(buffer, sizec, value, 16, sign, 0);
+ print_itoa(buffer, value, 16);
+ break;
+ case 'O':
+ case 'o':
+ sizec[i] = '\0';
+ value = (long int) var & convert[length_mod];
+ print_fill(buffer, sizec, value, 8, sign, 0);
+ print_itoa(buffer, value, 8);
+ break;
+ case 'p':
+ sizec[i] = '\0';
+ print_fill(buffer, sizec, (unsigned long) var, 16, ' ', 2);
+ **buffer = '0';
+ *buffer += 1;
+ **buffer = 'x';
+ *buffer += 1;
+ print_itoa(buffer,(unsigned long) var, 16);
+ break;
+ case 'c':
+ sizec[i] = '\0';
+ print_fill(buffer, sizec, 1, 10, ' ', 0);
+ **buffer = (unsigned long) var;
+ *buffer += 1;
+ break;
+ case 's':
+ sizec[i] = '\0';
+ sizei = strtoul(sizec, NULL, 10);
+ len = strlen((char *) var);
+ if(sizei > len) {
+ for(i = 0; i < (sizei - len); i++) {
+ **buffer = ' ';
+ *buffer += 1;
+ }
+ }
+ for(i = 0; i < strlen((char *) var); i++) {
+ **buffer = ((char *) var)[i];
+ *buffer += 1;
+ }
+ break;
+ case 'l':
+ form++;
+ if(*form == 'l') {
+ length_mod = sizeof(long long int);
+ } else {
+ form--;
+ length_mod = sizeof(long int);
+ }
+ break;
+ case 'h':
+ form++;
+ if(*form == 'h') {
+ length_mod = sizeof(signed char);
+ } else {
+ form--;
+ length_mod = sizeof(short int);
+ }
+ break;
+ default:
+ if(*form >= '0' && *form <= '9')
+ sizec[i++] = *form;
+ }
+ form++;
+ }
+
+
+ return (long int) (*buffer - start);
+}
+
+
+/*
+ * The vsnprintf function prints a formated strings into a buffer.
+ * BUG: buffer size checking does not fully work yet
+ */
+int
+vsnprintf(char *buffer, size_t bufsize, const char *format, va_list arg)
+{
+ char *ptr, *bstart;
+
+ bstart = buffer;
+ ptr = (char *) format;
+
+ while(*ptr != '\0' && (buffer - bstart) < bufsize)
+ {
+ if(*ptr == '%') {
+ char formstr[20];
+ int i=0;
+
+ do {
+ formstr[i] = *ptr;
+ ptr++;
+ i++;
+ } while(!(*ptr == 'd' || *ptr == 'i' || *ptr == 'u' || *ptr == 'x' || *ptr == 'X'
+ || *ptr == 'p' || *ptr == 'c' || *ptr == 's' || *ptr == '%'
+ || *ptr == 'O' || *ptr == 'o' ));
+ formstr[i++] = *ptr;
+ formstr[i] = '\0';
+ if(*ptr == '%') {
+ *buffer++ = '%';
+ } else {
+ print_format(&buffer, formstr, va_arg(arg, void *));
+ }
+ ptr++;
+ } else {
+
+ *buffer = *ptr;
+
+ buffer++;
+ ptr++;
+ }
+ }
+
+ *buffer = '\0';
+
+ return (buffer - bstart);
+}
diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c
new file mode 100644
index 0000000..0dfd737
--- /dev/null
+++ b/lib/libc/stdio/vsprintf.c
@@ -0,0 +1,19 @@
+/******************************************************************************
+ * 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 "stdio.h"
+
+int
+vsprintf(char *buffer, const char *format, va_list arg)
+{
+ return vsnprintf(buffer, 0x7fffffff, format, arg);
+}
diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c
new file mode 100644
index 0000000..b9603e9
--- /dev/null
+++ b/lib/libc/stdio/vsscanf.c
@@ -0,0 +1,131 @@
+/******************************************************************************
+ * 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 "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+
+
+static void
+_scanf(const char **buffer, const char *fmt, va_list *ap)
+{
+ int i;
+ int length = 0;
+
+ fmt++;
+
+ while(*fmt != '\0') {
+
+ char tbuf[256];
+
+ switch(*fmt) {
+ case 'd':
+ case 'i':
+ if(length == 0) length = 256;
+
+ for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) {
+ tbuf[i] = **buffer;
+ *buffer += 1;
+ }
+ tbuf[i] = '\0';
+
+ *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 10);
+ break;
+ case 'X':
+ case 'x':
+ if(length == 0) length = 256;
+
+ for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) {
+ tbuf[i] = **buffer;
+ *buffer += 1;
+ }
+ tbuf[i] = '\0';
+
+ *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 16);
+ break;
+ case 'O':
+ case 'o':
+ if(length == 0) length = 256;
+
+ for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) {
+ tbuf[i] = **buffer;
+ *buffer += 1;
+ }
+ tbuf[i] = '\0';
+
+ *(va_arg(*ap, int *)) = strtol(tbuf, NULL, 8);
+ break;
+ case 'c':
+ *(va_arg(*ap, char *)) = **buffer;
+ *buffer += 1;
+ if(length > 1)
+ for(i = 1; i < length; i++)
+ *buffer += 1;
+ break;
+ case 's':
+ if(length == 0) length = 256;
+
+ for(i = 0; **buffer != ' ' && **buffer != '\t' && **buffer != '\n' && i < length; i++) {
+ tbuf[i] = **buffer;
+ *buffer += 1;
+ }
+
+ tbuf[i] = '\0';
+
+ strcpy(va_arg(*ap, char *), tbuf);
+ break;
+ default:
+ if(*fmt >= '0' && *fmt <= '9')
+ length += *fmt - '0';
+ break;
+ }
+ fmt++;
+ }
+
+}
+
+
+int
+vsscanf(const char *buffer, const char *fmt, va_list ap)
+{
+
+ while(*fmt != '\0') {
+
+ if(*fmt == '%') {
+
+ char formstr[20];
+ 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' ));
+ formstr[i++] = *fmt;
+ formstr[i] = '\0';
+ if(*fmt != '%') {
+ while(*buffer == ' ' || *buffer == '\t' || *buffer == '\n')
+ buffer++;
+ _scanf(&buffer, formstr, &ap);
+ }
+
+ }
+
+ fmt++;
+
+ }
+
+ return 0;
+}
+
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
new file mode 100644
index 0000000..702f6d7
--- /dev/null
+++ b/lib/libc/stdlib/Makefile.inc
@@ -0,0 +1,22 @@
+# *****************************************************************************
+# * Copyright (c) 2004, 2008 IBM Corporation
+# * All rights reserved.
+# * This program and the accompanying materials
+# * are made available under the terms of the BSD License
+# * which accompanies this distribution, and is available at
+# * http://www.opensource.org/licenses/bsd-license.php
+# *
+# * Contributors:
+# * IBM Corporation - initial implementation
+# ****************************************************************************/
+
+
+STDLIB_SRC_C = error.c atoi.c atol.c strtoul.c strtol.c rand.c \
+ malloc.c memalign.c realloc.c free.c
+
+STDLIB_SRC_ASM =
+STDLIB_SRCS = $(STDLIB_SRC_C:%=$(STDLIBCMNDIR)/%) $(STDLIB_SRC_ASM:%=$(STDLIBCMNDIR)/%)
+STDLIB_OBJS = $(STDLIB_SRC_C:%.c=%.o) $(STDLIB_SRC_ASM:%.S=%.o)
+
+%.o : $(STDLIBCMNDIR)/%.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
diff --git a/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
new file mode 100644
index 0000000..81020ca
--- /dev/null
+++ b/lib/libc/stdlib/error.c
@@ -0,0 +1,15 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+
+int errno;
+
diff --git a/lib/libc/stdlib/free.c b/lib/libc/stdlib/free.c
new file mode 100644
index 0000000..9005450
--- /dev/null
+++ b/lib/libc/stdlib/free.c
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+
+#include "stdlib.h"
+#include "malloc_defs.h"
+
+void
+free(void *ptr)
+{
+ struct chunk *header;
+
+ header = (struct chunk *) ptr;
+ header--;
+ header->inuse = 0;
+
+}
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
new file mode 100644
index 0000000..b2a3138
--- /dev/null
+++ b/lib/libc/stdlib/malloc.c
@@ -0,0 +1,157 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+
+#include "stddef.h"
+#include "stdlib.h"
+#include "unistd.h"
+#include "malloc_defs.h"
+
+
+static int clean(void);
+
+
+/* act points to the end of the initialized heap and the start of uninitialized heap */
+static char *act;
+
+/* Pointers to start and end of heap: */
+static char *heap_start, *heap_end;
+
+
+/*
+ * Standard malloc function
+ */
+void *
+malloc(size_t size)
+{
+ char *header;
+ void *data;
+ size_t blksize; /* size of memory block including the chunk */
+
+ blksize = size + sizeof(struct chunk);
+
+ /* has malloc been called for the first time? */
+ if (act == 0) {
+ size_t initsize;
+ /* add some space so we have a good initial playground */
+ initsize = (blksize + 0x1000) & ~0x0fff;
+ /* get initial memory region with sbrk() */
+ heap_start = sbrk(initsize);
+ if (heap_start == (void*)-1)
+ return NULL;
+ heap_end = heap_start + initsize;
+ act = heap_start;
+ }
+
+ header = act;
+ data = act + sizeof(struct chunk);
+
+ /* Check if there is space left in the uninitialized part of the heap */
+ if (act + blksize > heap_end) {
+ //search at begin of heap
+ header = heap_start;
+
+ while ((((struct chunk *) header)->inuse != 0
+ || ((struct chunk *) header)->length < size)
+ && header < act) {
+ header = header + sizeof(struct chunk)
+ + ((struct chunk *) header)->length;
+ }
+
+ // check if heap is full
+ if (header >= act) {
+ if (clean()) {
+ // merging of free blocks succeeded, so try again
+ return malloc(size);
+ } else if (sbrk(blksize) == heap_end) {
+ // succeeded to get more memory, so try again
+ heap_end += blksize;
+ return malloc(size);
+ } else {
+ // No more memory available
+ return 0;
+ }
+ }
+
+ // Check if we need to split this memory block into two
+ if (((struct chunk *) header)->length > blksize) {
+ //available memory is too big
+ int alt;
+
+ alt = ((struct chunk *) header)->length;
+ ((struct chunk *) header)->inuse = 1;
+ ((struct chunk *) header)->length = size;
+ data = header + sizeof(struct chunk);
+
+ //mark the rest of the heap
+ header = data + size;
+ ((struct chunk *) header)->inuse = 0;
+ ((struct chunk *) header)->length =
+ alt - blksize;
+ } else {
+ //new memory matched exactly in available memory
+ ((struct chunk *) header)->inuse = 1;
+ data = header + sizeof(struct chunk);
+ }
+
+ } else {
+
+ ((struct chunk *) header)->inuse = 1;
+ ((struct chunk *) header)->length = size;
+
+ act += blksize;
+ }
+
+ return data;
+}
+
+
+/*
+ * Merge free memory blocks in initialized heap if possible
+ */
+static int
+clean(void)
+{
+ char *header;
+ char *firstfree = 0;
+ char check = 0;
+
+ header = heap_start;
+ //if (act == 0) // This should never happen
+ // act = heap_end;
+
+ while (header < act) {
+
+ if (((struct chunk *) header)->inuse == 0) {
+ if (firstfree == 0) {
+ /* First free block in a row, only save address */
+ firstfree = header;
+
+ } else {
+ /* more than one free block in a row, merge them! */
+ ((struct chunk *) firstfree)->length +=
+ ((struct chunk *) header)->length +
+ sizeof(struct chunk);
+ check = 1;
+ }
+ } else {
+ firstfree = 0;
+
+ }
+
+ header = header + sizeof(struct chunk)
+ + ((struct chunk *) header)->length;
+
+ }
+
+ return check;
+}
diff --git a/lib/libc/stdlib/malloc_defs.h b/lib/libc/stdlib/malloc_defs.h
new file mode 100644
index 0000000..1933026
--- /dev/null
+++ b/lib/libc/stdlib/malloc_defs.h
@@ -0,0 +1,16 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+struct chunk {
+ unsigned inuse : 4;
+ unsigned length : 28;
+} __attribute__((packed));
diff --git a/lib/libc/stdlib/memalign.c b/lib/libc/stdlib/memalign.c
new file mode 100644
index 0000000..3b678aa
--- /dev/null
+++ b/lib/libc/stdlib/memalign.c
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+
+#include "stdlib.h"
+
+
+void *
+memalign(size_t blocksize, size_t bytes)
+{
+ void *x;
+
+ x = malloc(bytes + blocksize);
+ x = (void *) (((unsigned long) x + blocksize - 1) & ~(blocksize - 1));
+
+ return (void *) x;
+}
diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c
new file mode 100644
index 0000000..87e3efd
--- /dev/null
+++ b/lib/libc/stdlib/rand.c
@@ -0,0 +1,24 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include <stdlib.h>
+
+
+static unsigned long _rand = 1;
+
+int
+rand(void)
+{
+ _rand = _rand * 25364735 + 34563;
+
+ return ((unsigned int) (_rand << 16) & RAND_MAX);
+}
diff --git a/lib/libc/stdlib/realloc.c b/lib/libc/stdlib/realloc.c
new file mode 100644
index 0000000..652e900
--- /dev/null
+++ b/lib/libc/stdlib/realloc.c
@@ -0,0 +1,40 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+
+#include "stdlib.h"
+#include "string.h"
+#include "malloc_defs.h"
+
+void *
+realloc(void *ptr, size_t size)
+{
+ struct chunk *header;
+ char *newptr, *start;
+
+ header = (struct chunk *) ptr;
+ header--;
+
+ if (size <= header->length)
+ return ptr;
+
+ newptr = (char *) malloc(size);
+ if (newptr == NULL)
+ return 0;
+
+ start = newptr;
+ memcpy((void *) newptr, (const void *) ptr, header->length);
+
+ header->inuse = 0;
+
+ return start;
+}
diff --git a/lib/libc/stdlib/strtol.c b/lib/libc/stdlib/strtol.c
new file mode 100644
index 0000000..aae5e54
--- /dev/null
+++ b/lib/libc/stdlib/strtol.c
@@ -0,0 +1,113 @@
+/******************************************************************************
+ * 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
+ *****************************************************************************/
+
+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
new file mode 100644
index 0000000..3a86c50
--- /dev/null
+++ b/lib/libc/stdlib/strtoul.c
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * 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
+ *****************************************************************************/
+
+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
new file mode 100644
index 0000000..7ccf3c4
--- /dev/null
+++ b/lib/libc/string/Makefile.inc
@@ -0,0 +1,22 @@
+# *****************************************************************************
+# * Copyright (c) 2004, 2008 IBM Corporation
+# * All rights reserved.
+# * This program and the accompanying materials
+# * are made available under the terms of the BSD License
+# * which accompanies this distribution, and is available at
+# * http://www.opensource.org/licenses/bsd-license.php
+# *
+# * Contributors:
+# * IBM Corporation - initial implementation
+# ****************************************************************************/
+
+
+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 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)
+
+%.o : $(STRINGCMNDIR)/%.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
diff --git a/lib/libc/string/memchr.c b/lib/libc/string/memchr.c
new file mode 100644
index 0000000..c3fe751
--- /dev/null
+++ b/lib/libc/string/memchr.c
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * 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"
+
+
+void *
+memchr(const void *ptr, int c, size_t n)
+{
+ unsigned char ch = (unsigned char)c;
+ const unsigned char *p = ptr;
+
+ while (n-- > 0) {
+ if (*p == ch)
+ return (void *)p;
+ p += 1;
+ }
+
+ return NULL;
+}
diff --git a/lib/libc/string/memcmp.c b/lib/libc/string/memcmp.c
new file mode 100644
index 0000000..3b69cef
--- /dev/null
+++ b/lib/libc/string/memcmp.c
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * 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"
+
+
+int
+memcmp(const void *ptr1, const void *ptr2, size_t n)
+{
+ const unsigned char *p1 = ptr1;
+ const unsigned char *p2 = ptr2;
+
+ while (n-- > 0) {
+ if (*p1 != *p2)
+ return (*p1 - *p2);
+ p1 += 1;
+ p2 += 1;
+ }
+
+ return 0;
+}
diff --git a/lib/libc/string/memcpy.c b/lib/libc/string/memcpy.c
new file mode 100644
index 0000000..00f419b
--- /dev/null
+++ b/lib/libc/string/memcpy.c
@@ -0,0 +1,27 @@
+/******************************************************************************
+ * 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"
+
+void *
+memcpy(void *dest, const void *src, size_t n)
+{
+ char *cdest;
+ const char *csrc = src;
+
+ cdest = dest;
+ while (n-- > 0) {
+ *cdest++ = *csrc++;
+ }
+
+ return dest;
+}
diff --git a/lib/libc/string/memmove.c b/lib/libc/string/memmove.c
new file mode 100644
index 0000000..3acf1a9
--- /dev/null
+++ b/lib/libc/string/memmove.c
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * 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"
+
+
+void *
+memmove(void *dest, const void *src, size_t n)
+{
+ char *cdest;
+ const char *csrc;
+ int i;
+
+ /* Do the buffers overlap in a bad way? */
+ if (src < dest && src + n >= dest) {
+ /* Copy from end to start */
+ cdest = dest + n - 1;
+ csrc = src + n - 1;
+ for (i = 0; i < n; i++) {
+ *cdest-- = *csrc--;
+ }
+ }
+ else {
+ /* Normal copy is possible */
+ cdest = dest;
+ csrc = src;
+ for (i = 0; i < n; i++) {
+ *cdest++ = *csrc++;
+ }
+ }
+
+ return dest;
+}
diff --git a/lib/libc/string/memset.c b/lib/libc/string/memset.c
new file mode 100644
index 0000000..f8dfbf5
--- /dev/null
+++ b/lib/libc/string/memset.c
@@ -0,0 +1,25 @@
+/******************************************************************************
+ * 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"
+
+void *
+memset(void *dest, int c, size_t size)
+{
+ unsigned char *d = (unsigned char *)dest;
+
+ while (size-- > 0) {
+ *d++ = (unsigned char)c;
+ }
+
+ return dest;
+}
diff --git a/lib/libc/string/strcasecmp.c b/lib/libc/string/strcasecmp.c
new file mode 100644
index 0000000..f75294f
--- /dev/null
+++ b/lib/libc/string/strcasecmp.c
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * 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>
+#include <ctype.h>
+
+int
+strcasecmp(const char *s1, const char *s2)
+{
+ while (*s1 != 0 && *s2 != 0) {
+ if (toupper(*s1) != toupper(*s2))
+ break;
+ ++s1;
+ ++s2;
+ }
+
+ return *s1 - *s2;
+}
+
diff --git a/lib/libc/string/strcat.c b/lib/libc/string/strcat.c
new file mode 100644
index 0000000..eb597a0
--- /dev/null
+++ b/lib/libc/string/strcat.c
@@ -0,0 +1,24 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include <string.h>
+
+char *
+strcat(char *dst, const char *src)
+{
+ int p;
+
+ p = strlen(dst);
+ strcpy(&dst[p], src);
+
+ return dst;
+}
diff --git a/lib/libc/string/strchr.c b/lib/libc/string/strchr.c
new file mode 100644
index 0000000..528a319
--- /dev/null
+++ b/lib/libc/string/strchr.c
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * 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 *
+strchr(const char *s, int c)
+{
+ char cb = c;
+
+ while (*s != 0) {
+ if (*s == cb) {
+ return (char *)s;
+ }
+ s += 1;
+ }
+
+ return NULL;
+}
diff --git a/lib/libc/string/strcmp.c b/lib/libc/string/strcmp.c
new file mode 100644
index 0000000..48eaed2
--- /dev/null
+++ b/lib/libc/string/strcmp.c
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * 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>
+
+
+int
+strcmp(const char *s1, const char *s2)
+{
+ while (*s1 != 0 && *s2 != 0) {
+ if (*s1 != *s2)
+ break;
+ s1 += 1;
+ s2 += 1;
+ }
+
+ return *s1 - *s2;
+}
+
diff --git a/lib/libc/string/strcpy.c b/lib/libc/string/strcpy.c
new file mode 100644
index 0000000..48eb62c
--- /dev/null
+++ b/lib/libc/string/strcpy.c
@@ -0,0 +1,25 @@
+/******************************************************************************
+ * 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 *
+strcpy(char *dst, const char *src)
+{
+ char *ptr = dst;
+
+ do {
+ *ptr++ = *src;
+ } while (*src++ != 0);
+
+ return dst;
+}
diff --git a/lib/libc/string/strlen.c b/lib/libc/string/strlen.c
new file mode 100644
index 0000000..37a1b78
--- /dev/null
+++ b/lib/libc/string/strlen.c
@@ -0,0 +1,27 @@
+/******************************************************************************
+ * 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>
+
+size_t
+strlen(const char *s)
+{
+ int len = 0;
+
+ while (*s != 0) {
+ len += 1;
+ s += 1;
+ }
+
+ return len;
+}
+
diff --git a/lib/libc/string/strncasecmp.c b/lib/libc/string/strncasecmp.c
new file mode 100644
index 0000000..4140931
--- /dev/null
+++ b/lib/libc/string/strncasecmp.c
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * 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>
+#include <ctype.h>
+
+
+int
+strncasecmp(const char *s1, const char *s2, size_t n)
+{
+ if (n < 1)
+ return 0;
+
+ while (*s1 != 0 && *s2 != 0 && --n > 0) {
+ if (toupper(*s1) != toupper(*s2))
+ break;
+ ++s1;
+ ++s2;
+ }
+
+ return toupper(*s1) - toupper(*s2);
+}
+
diff --git a/lib/libc/string/strncmp.c b/lib/libc/string/strncmp.c
new file mode 100644
index 0000000..a886736
--- /dev/null
+++ b/lib/libc/string/strncmp.c
@@ -0,0 +1,31 @@
+/******************************************************************************
+ * 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>
+
+
+int
+strncmp(const char *s1, const char *s2, size_t n)
+{
+ if (n < 1)
+ return 0;
+
+ while (*s1 != 0 && *s2 != 0 && --n > 0) {
+ if (*s1 != *s2)
+ break;
+ s1 += 1;
+ s2 += 1;
+ }
+
+ return *s1 - *s2;
+}
+
diff --git a/lib/libc/string/strncpy.c b/lib/libc/string/strncpy.c
new file mode 100644
index 0000000..0f41f93
--- /dev/null
+++ b/lib/libc/string/strncpy.c
@@ -0,0 +1,33 @@
+/******************************************************************************
+ * 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 *
+strncpy(char *dst, const char *src, size_t n)
+{
+ char *ret = dst;
+
+ /* Copy string */
+ while (*src != 0 && n > 0) {
+ *dst++ = *src++;
+ n -= 1;
+ }
+
+ /* strncpy always clears the rest of destination string... */
+ while (n > 0) {
+ *dst++ = 0;
+ n -= 1;
+ }
+
+ return ret;
+}
diff --git a/lib/libc/string/strstr.c b/lib/libc/string/strstr.c
new file mode 100644
index 0000000..3e090d2
--- /dev/null
+++ b/lib/libc/string/strstr.c
@@ -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
+ *****************************************************************************/
+
+#include <string.h>
+
+char *
+strstr(const char *hay, const char *needle)
+{
+ char *pos;
+ int hlen, nlen;
+
+ if (hay == NULL || needle == NULL)
+ return NULL;
+
+ hlen = strlen(hay);
+ nlen = strlen(needle);
+ if (nlen < 1)
+ return (char *)hay;
+
+ for (pos = (char *)hay; pos < hay + hlen; pos++) {
+ if (strncmp(pos, needle, nlen) == 0) {
+ return pos;
+ }
+ }
+
+ return NULL;
+}
+
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
new file mode 100644
index 0000000..82ef0bb
--- /dev/null
+++ b/lib/libelf/Makefile
@@ -0,0 +1,47 @@
+# *****************************************************************************
+# * 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
+# ****************************************************************************/
+
+TOPCMNDIR ?= ../..
+
+include $(TOPCMNDIR)/make.rules
+
+CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLCMNDIR) -I$(INCLCMNDIR)/$(CPUARCH)
+LDFLAGS= -nostdlib
+
+TARGET = ../libelf.a
+
+all: $(TARGET)
+
+SRCS = elf.c
+
+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
+ $(CC) -MM $(CPPFLAGS) $(CFLAGS) $(SRCS) > Makefile.dep
+
+# Include dependency file if available:
+-include Makefile.dep
diff --git a/lib/libelf/elf.c b/lib/libelf/elf.c
new file mode 100644
index 0000000..359f628
--- /dev/null
+++ b/lib/libelf/elf.c
@@ -0,0 +1,234 @@
+/******************************************************************************
+ * 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
+ *****************************************************************************/
+
+/* this is elf.fs rewritten in C */
+
+#include <string.h>
+#include <cpu.h>
+#include <libelf.h>
+
+struct ehdr {
+ unsigned int ei_ident;
+ unsigned char ei_class;
+ unsigned char ei_data;
+ unsigned char ei_version;
+ unsigned char ei_pad[9];
+ unsigned short e_type;
+ unsigned short e_machine;
+ unsigned int e_version;
+ unsigned int e_entry;
+ unsigned int e_phoff;
+ unsigned int e_shoff;
+ unsigned int e_flags;
+ unsigned short e_ehsize;
+ unsigned short e_phentsize;
+ unsigned short e_phnum;
+ unsigned short e_shentsize;
+ unsigned short e_shnum;
+ unsigned short e_shstrndx;
+};
+
+struct phdr {
+ unsigned int p_type;
+ unsigned int p_offset;
+ unsigned int p_vaddr;
+ unsigned int p_paddr;
+ unsigned int p_filesz;
+ unsigned int p_memsz;
+ unsigned int p_flags;
+ unsigned int p_align;
+};
+
+struct ehdr64 {
+ unsigned int ei_ident;
+ unsigned char ei_class;
+ unsigned char ei_data;
+ unsigned char ei_version;
+ unsigned char ei_pad[9];
+ unsigned short e_type;
+ unsigned short e_machine;
+ unsigned int e_version;
+ unsigned long e_entry;
+ unsigned long e_phoff;
+ unsigned long e_shoff;
+ unsigned int e_flags;
+ unsigned short e_ehsize;
+ unsigned short e_phentsize;
+ unsigned short e_phnum;
+ unsigned short e_shentsize;
+ unsigned short e_shnum;
+ unsigned short e_shstrndx;
+};
+
+struct phdr64 {
+ unsigned int p_type;
+ unsigned int p_flags;
+ unsigned long p_offset;
+ unsigned long p_vaddr;
+ unsigned long p_paddr;
+ unsigned long p_filesz;
+ unsigned long p_memsz;
+ unsigned long p_align;
+};
+
+#define VOID(x) (void *)((unsigned long)x)
+
+static void
+load_segment(unsigned long *file_addr, struct phdr *phdr)
+{
+ unsigned long src = phdr->p_offset + (unsigned long) file_addr;
+ /* copy into storage */
+ memmove(VOID(phdr->p_vaddr), VOID(src), phdr->p_filesz);
+
+ /* clear bss */
+ memset(VOID(phdr->p_vaddr + phdr->p_filesz), 0,
+ phdr->p_memsz - phdr->p_filesz);
+
+ if (phdr->p_memsz) {
+ flush_cache(VOID(phdr->p_vaddr), phdr->p_memsz);
+ }
+}
+
+static unsigned int
+load_segments(unsigned long *file_addr)
+{
+ struct ehdr *ehdr = (struct ehdr *) file_addr;
+ /* Calculate program header address */
+ struct phdr *phdr =
+ (struct phdr *) (((unsigned char *) file_addr) + ehdr->e_phoff);
+ int i;
+ /* loop e_phnum times */
+ for (i = 0; i <= ehdr->e_phnum; i++) {
+ /* PT_LOAD ? */
+ if (phdr->p_type == 1) {
+ /* copy segment */
+ load_segment(file_addr, phdr);
+ }
+ /* step to next header */
+ phdr =
+ (struct phdr *) (((unsigned char *) phdr) +
+ ehdr->e_phentsize);
+ }
+ return ehdr->e_entry;
+}
+
+static void
+load_segment64(unsigned long *file_addr, struct phdr64 *phdr64)
+{
+ unsigned long src = phdr64->p_offset + (unsigned long) file_addr;
+ /* copy into storage */
+ memmove(VOID(phdr64->p_vaddr), VOID(src), phdr64->p_filesz);
+
+ /* clear bss */
+ memset(VOID(phdr64->p_vaddr + phdr64->p_filesz), 0,
+ phdr64->p_memsz - phdr64->p_filesz);
+
+ if (phdr64->p_memsz) {
+ flush_cache(VOID(phdr64->p_vaddr), phdr64->p_memsz);
+ }
+}
+
+static unsigned long
+load_segments64(unsigned long *file_addr)
+{
+ struct ehdr64 *ehdr64 = (struct ehdr64 *) file_addr;
+ /* Calculate program header address */
+ struct phdr64 *phdr64 =
+ (struct phdr64 *) (((unsigned char *) file_addr) + ehdr64->e_phoff);
+ int i;
+ /* loop e_phnum times */
+ for (i = 0; i <= ehdr64->e_phnum; i++) {
+ /* PT_LOAD ? */
+ if (phdr64->p_type == 1) {
+ /* copy segment */
+ load_segment64(file_addr, phdr64);
+ }
+ /* step to next header */
+ phdr64 =
+ (struct phdr64 *) (((unsigned char *) phdr64) +
+ ehdr64->e_phentsize);
+ }
+ return ehdr64->e_entry;
+}
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define cpu_to_be32(x) (x)
+#else
+#define cpu_to_be32(x) bswap_32(x)
+#endif
+
+/**
+ * elf_check_file tests if the file at file_addr is
+ * a correct endian, ELF PPC executable
+ * @param file_addr pointer to the start of the ELF file
+ * @return the class (1 for 32 bit, 2 for 64 bit)
+ * -1 if it is not an ELF file
+ * -2 if it has the wrong endianess
+ * -3 if it is not an ELF executable
+ * -4 if it is not for PPC
+ */
+static int
+elf_check_file(unsigned long *file_addr)
+{
+ struct ehdr *ehdr = (struct ehdr *) file_addr;
+ /* check if it is an ELF image at all */
+ if (cpu_to_be32(ehdr->ei_ident) != 0x7f454c46)
+ return -1;
+
+ /* endian check */
+#if __BYTE_ORDER == __BIG_ENDIAN
+ if (ehdr->ei_data != 2)
+ /* not a big endian image */
+#else
+ if (ehdr->ei_data == 2)
+ /* not a little endian image */
+#endif
+ return -2;
+
+ /* check if it is an ELF executable */
+ if (ehdr->e_type != 2)
+ return -3;
+
+ /* check if it is a PPC ELF executable */
+ if (ehdr->e_machine != 0x14 && ehdr->e_machine != 0x15)
+ return -4;
+
+ return ehdr->ei_class;
+}
+
+/**
+ * load_elf_file tries to load the ELF file specified in file_addr
+ *
+ * it first checks if the file is a PPC ELF executable and then loads
+ * the segments depending if it is a 64bit or 32 bit ELF file
+ *
+ * @param file_addr pointer to the start of the elf file
+ * @param entry pointer where the ELF loader will store
+ * the entry point
+ * @return 1 for a 32 bit file
+ * 2 for a 64 bit file
+ * anything else means an error during load
+ */
+int
+load_elf_file(unsigned long *file_addr, unsigned long *entry)
+{
+ int type = elf_check_file(file_addr);
+ switch (type) {
+ case 1:
+ *entry = load_segments(file_addr);
+ break;
+ case 2:
+ *entry = load_segments64(file_addr);
+ break;
+ }
+ return type;
+}
diff --git a/lib/libelf/libelf.code b/lib/libelf/libelf.code
new file mode 100644
index 0000000..6e019fc
--- /dev/null
+++ b/lib/libelf/libelf.code
@@ -0,0 +1,21 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+int load_elf_file(unsigned long *file_addr, unsigned long *entry);
+
+PRIM(LOADELF)
+ void *file_addr = TOS.a;
+ int type;
+ unsigned long entry;
+ type = load_elf_file(file_addr, &entry);
+ TOS.u = entry;
+ PUSH; TOS.n = type;
+MIRP
diff --git a/lib/libelf/libelf.in b/lib/libelf/libelf.in
new file mode 100644
index 0000000..1fea40c
--- /dev/null
+++ b/lib/libelf/libelf.in
@@ -0,0 +1,12 @@
+/******************************************************************************
+ * 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
+ *****************************************************************************/
+cod(LOADELF)
diff --git a/lib/libipmi/Makefile b/lib/libipmi/Makefile
new file mode 100644
index 0000000..4777f9e
--- /dev/null
+++ b/lib/libipmi/Makefile
@@ -0,0 +1,28 @@
+# *****************************************************************************
+# * Copyright (c) 2004, 2007 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
+# ****************************************************************************/
+
+TOPCMNDIR ?= ../..
+
+LIBIPMICMNDIR = $(shell pwd)
+
+include $(TOPCMNDIR)/make.rules
+
+TARGET = ../libipmi.a
+
+all: $(TARGET)
+
+$(TARGET):
+ cp libipmi.oco $@
+
+clean:
+
+distclean:
diff --git a/lib/libipmi/libipmi.code b/lib/libipmi/libipmi.code
new file mode 100644
index 0000000..59c1244
--- /dev/null
+++ b/lib/libipmi/libipmi.code
@@ -0,0 +1,120 @@
+/******************************************************************************
+ * 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 <libipmi.h>
+
+// : ipmi-kcs-cmd ( in-buf in-len out-buf out-maxlen -- out-len errorcode )
+PRIM(IPMI_X2d_KCS_X2d_CMD)
+ cell maxlen = TOS; POP;
+ cell outbuf = TOS; POP;
+ int len = TOS.n; POP;
+ cell inbuf = TOS;
+ int retval;
+ retval = ipmi_kcs_cmd(inbuf.a, outbuf.a, maxlen.n, (uint32_t *) &len);
+ TOS.n = len;
+ PUSH; TOS.n = retval;
+MIRP
+
+
+PRIM(IPMI_X2d_SYSTEM_X2d_REBOOT)
+ ipmi_system_reboot();
+MIRP
+
+
+PRIM(IPMI_X2d_POWER_X2d_OFF)
+ ipmi_power_off();
+MIRP
+
+
+// : ipmi-oem-stop-bootwatchdog ( -- errorcode )
+PRIM(IPMI_X2d_OEM_X2d_STOP_X2d_BOOTWATCHDOG)
+ PUSH;
+ TOS.n = ipmi_oem_stop_bootwatchdog();
+MIRP
+
+
+// : ipmi-oem-set-bootwatchdog ( seconds -- errorcode )
+PRIM(IPMI_X2d_OEM_X2d_SET_X2d_BOOTWATCHDOG)
+ int sec = TOS.n;
+ TOS.n = ipmi_oem_set_bootwatchdog(sec);
+MIRP
+
+
+// : ipmi-oem-reset-bootwatchdog ( -- errorcode )
+PRIM(IPMI_X2d_OEM_X2d_RESET_X2d_BOOTWATCHDOG)
+ PUSH;
+ TOS.n = ipmi_oem_reset_bootwatchdog();
+MIRP
+
+
+// : ipmi-oem-led-set ( type instance state -- errorcode )
+PRIM(IPMI_X2d_OEM_X2d_LED_X2d_SET)
+ int state = TOS.n; POP;
+ int instance = TOS.n; POP;
+ int type = TOS.n;
+ TOS.n = ipmi_oem_led_set(type, instance, state);
+MIRP
+
+
+// : ipmi-oem-read-vpd ( offset length dst -- status )
+PRIM(IPMI_X2d_OEM_X2d_READ_X2d_VPD)
+ cell dest = TOS; POP;
+ int len = TOS.n; POP;
+ int offset = TOS.n;
+ TOS.n = ipmi_oem_read_vpd(dest.a, len, offset);
+MIRP
+
+// : ipmi-oem-write-vpd ( offset length src -- status )
+PRIM(IPMI_X2d_OEM_X2d_WRITE_X2d_VPD)
+ cell src = TOS; POP;
+ int len = TOS.n; POP;
+ int offset = TOS.n;
+ TOS.n = ipmi_oem_write_vpd(src.a, len, offset);
+MIRP
+
+
+// : ipmi-oem-get-blade-descr ( buf maxlen -- len status )
+PRIM(IPMI_X2d_OEM_X2d_GET_X2d_BLADE_X2d_DESCR)
+ int maxlen = TOS.n; POP;
+ cell buf = TOS;
+ int len = 0;
+ int retval;
+ retval = ipmi_oem_get_blade_descr(buf.a, maxlen, (uint32_t *) &len);
+ TOS.n = len;
+ PUSH; TOS.n = retval;
+MIRP
+
+
+// : ipmi-oem-bios2sp ( str-ptr str-len swid type -- errorcode )
+PRIM(IPMI_X2d_OEM_X2d_BIOS2SP)
+ int type = TOS.n; POP;
+ int swid = TOS.n; POP;
+ int len = TOS.n; POP;
+ void* addr = TOS.a;
+ 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
new file mode 100644
index 0000000..9ac8308
--- /dev/null
+++ b/lib/libipmi/libipmi.h
@@ -0,0 +1,33 @@
+/******************************************************************************
+ * 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 __LIBIPMI_H
+#define __LIBIPMI_H
+
+#include <stdint.h>
+
+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);
+extern int ipmi_oem_reset_bootwatchdog(void);
+extern int ipmi_oem_led_set(int type, int instance, int state);
+extern uint32_t ipmi_oem_read_vpd(uint8_t *dst, uint32_t len, uint32_t offset);
+extern uint32_t ipmi_oem_write_vpd(uint8_t *src, uint32_t len, uint32_t offset);
+extern uint32_t ipmi_oem_get_blade_descr(uint8_t *dst, uint32_t maxlen, uint32_t *len);
+extern int ipmi_oem_bios2sp(int swid, int type, char *data, int len);
+
+#endif
diff --git a/lib/libipmi/libipmi.in b/lib/libipmi/libipmi.in
new file mode 100644
index 0000000..5b0e0ec
--- /dev/null
+++ b/lib/libipmi/libipmi.in
@@ -0,0 +1,24 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+cod(IPMI-KCS-CMD)
+cod(IPMI-SYSTEM-REBOOT)
+cod(IPMI-POWER-OFF)
+cod(IPMI-OEM-STOP-BOOTWATCHDOG)
+cod(IPMI-OEM-SET-BOOTWATCHDOG)
+cod(IPMI-OEM-RESET-BOOTWATCHDOG)
+cod(IPMI-OEM-LED-SET)
+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