From 34fda6d85036bae126f253191a44e5f72fb252bc Mon Sep 17 00:00:00 2001
From: root <root@ubuntu.(none)>
Date: Thu, 31 May 2007 10:39:23 -0400
Subject: [PATCH] Update to the stand alone program feature

-The #ifdef maze was removed and is now handled by the linker (idea from Haavard)
-Documentation was updated
-more functions were added to the exports list

Signed-off-by: Jeffrey Mann <mannj@embeddedplanet.com>
---
 Makefile              |   12 ++++++++++++
 common/exports.c      |   40 ++++++++++++++++++++++++----------------
 doc/README.standalone |   35 ++++++++++++++++++++++++++++++-----
 include/_exports.h    |   23 +++++++++++++++++++++--
 include/exports.h     |   38 +++++++++++++++++++++++++++++---------
 mkconfig              |    6 ++++++
 6 files changed, 122 insertions(+), 32 deletions(-)

diff --git a/Makefile b/Makefile
index caa5a0e..2485b96
--- a/Makefile
+++ b/Makefile
@@ -234,6 +234,12 @@ # The "tools" are needed early, so put t
 # Don't include stuff already done in $(LIBS)
 SUBDIRS	= tools \
 	  examples
+	  
+# Include a directory with a stand alone program in it if the user has configured
+# u-boot for it. (This is done using the SA= flag. See README.standalone)	  
+ifeq ($(COMPILE_STAND_ALONE),y)
+SUBDIRS += $(STAND_ALONE_DIR)
+endif
 
 .PHONY : $(SUBDIRS)
 
@@ -2443,6 +2449,12 @@ clean:
 	rm -f $(obj)board/bf537-stamp/u-boot.lds $(obj)board/bf561-ezkit/u-boot.lds
 	rm -f $(obj)include/bmp_logo.h
 	rm -f $(obj)nand_spl/u-boot-spl $(obj)nand_spl/u-boot-spl.map
+ifeq ($(COMPILE_STAND_ALONE),y)
+	find $(STAND_ALONE_DIR) -type f \
+		\( -name 'core' -o -name '*.bak' -o -name '*~' \
+		-o -name '*.o'  -o -name '*.a'  \) -print \
+		| xargs rm -f
+endif
 
 clobber:	clean
 	find $(OBJTREE) -type f \( -name .depend \
diff --git a/common/exports.c b/common/exports.c
index 0cb4396..5af2a06
--- a/common/exports.c
+++ b/common/exports.c
@@ -7,6 +7,26 @@ static void dummy(void)
 {
 }
 
+#define EXPORT_FUNC(x) asm(".weak\t" #x "\n\t.set\t" #x ",dummy");
+#include <_exports.h>
+#undef EXPORT_FUNC
+
+/*
+ * xf_func_inc(int) is used to determine whether a function has been compiled 
+ * with u-boot and available for use by a stand alone program . This allows a 
+ * stand alone program to ensure that a function exists before running code with
+ * the an exported function in it. 
+ *
+ * function_id is defined by the enum type of _exports.h. For example, 
+ *   xf_func_inc(XF_foobar)
+ *   returns 0 if the function foobar() is available
+ *   returns 1 if the function foobar() has not been compiled with u-boot 
+ */
+int xf_func_inc(int function_id)
+{		
+	return (gd->jt[function_id] == (void *) dummy);
+}
+
 unsigned long get_version(void)
 {
 	return XF_VERSION;
@@ -20,20 +40,8 @@ void jumptable_init (void)
 	for (i = 0; i < XF_MAX; i++)
 		gd->jt[i] = (void *) dummy;
 
-	gd->jt[XF_get_version] = (void *) get_version;
-	gd->jt[XF_malloc] = (void *) malloc;
-	gd->jt[XF_free] = (void *) free;
-	gd->jt[XF_getenv] = (void *) getenv;
-	gd->jt[XF_setenv] = (void *) setenv;
-	gd->jt[XF_get_timer] = (void *) get_timer;
-	gd->jt[XF_simple_strtoul] = (void *) simple_strtoul;
-	gd->jt[XF_udelay] = (void *) udelay;
-#if defined(CONFIG_I386) || defined(CONFIG_PPC)
-	gd->jt[XF_install_hdlr] = (void *) irq_install_handler;
-	gd->jt[XF_free_hdlr] = (void *) irq_free_handler;
-#endif	/* I386 || PPC */
-#if (CONFIG_COMMANDS & CFG_CMD_I2C)
-	gd->jt[XF_i2c_write] = (void *) i2c_write;
-	gd->jt[XF_i2c_read] = (void *) i2c_read;
-#endif	/* CFG_CMD_I2C */
+#define EXPORT_FUNC(x) gd->jt[XF_ ## x ] = (void *) x ;
+#include <_exports.h>
+#undef EXPORT_FUNC
+
 }
diff --git a/doc/README.standalone b/doc/README.standalone
index 3998831..37376ed
--- a/doc/README.standalone
+++ b/doc/README.standalone
@@ -68,17 +68,18 @@ Design Notes on Exporting U-Boot Functio
      file:
 
 	EXPORT_FUNC(foobar)
+	
+	 It is important that these be appended to the end of the file so
+	 that the order of existing functions on the list does not change. 
+	 Also, functions in _exports.h should NOT be wrapped in #ifdef 
+	 statements.
+ 
 
    - Add the prototype for this function to the include/exports.h
      file:
 
 	void foobar(void);
 
-   - Add the initialization of the jump table slot wherever
-     appropriate (most likely, to the jumptable_init() function):
-
-	gd->jt[XF_foobar] = foobar;
-
    - Increase the XF_VERSION value by one in the include/exports.h
      file
 
@@ -94,3 +95,27 @@ Design Notes on Exporting U-Boot Functio
    Note that these functions may only use call-clobbered registers;
    those registers that are used to pass the function's arguments,
    the stack contents and the return address should be left intact.
+
+7. To include a directory containing a stand alone program, use the 
+   SA= flag when selecting the board. This is optional, but provides
+   a convenient way to compile the stand alone program at the same
+   time as u-boot. For example:
+   
+   make BOARD_config SA=diagprog
+   
+   The directory 'diagprog' will be included as a subdirectory when 
+   u-boot is compiled. This allows for stand alone programs not kept
+   in the u-boot tree to be easily compiled with u-boot without 
+   changing the Makefile to accommodate them. 
+
+8. A stand alone program may call xf_func_inc( ) to discover if a 
+   certain function has been compiled with u-boot and therefore
+   available for use by the stand alone program. For example:
+   
+   xf_func_inc(XF_foobar)
+   
+   will return 0 if the function foobar() has been compiled with u-boot, 
+   and 1 if the function has not been compiled with u-boot. This
+   feature allows for a stand alone program to check for the
+   presence of a certain optional u-boot feature before attempting
+   to utilize it.
\ No newline at end of file
diff --git a/include/_exports.h b/include/_exports.h
index 2b8ec3d..0e6a33e
--- a/include/_exports.h
+++ b/include/_exports.h
@@ -15,7 +15,26 @@ EXPORT_FUNC(do_reset)
 EXPORT_FUNC(getenv)
 EXPORT_FUNC(setenv)
 EXPORT_FUNC(simple_strtoul)
-#if (CONFIG_COMMANDS & CFG_CMD_I2C)
+EXPORT_FUNC(xf_func_inc)
+EXPORT_FUNC(ctrlc)
+EXPORT_FUNC(sprintf)
+EXPORT_FUNC(strcmp)
+EXPORT_FUNC(saveenv)
+EXPORT_FUNC(out8)
+EXPORT_FUNC(in8)
+EXPORT_FUNC(in16)
+EXPORT_FUNC(out16)
+EXPORT_FUNC(in32)
+EXPORT_FUNC(out32)
+EXPORT_FUNC(netboot_common)
+EXPORT_FUNC(do_nand)
+EXPORT_FUNC(rtc_get)
+EXPORT_FUNC(do_date)
 EXPORT_FUNC(i2c_write)
 EXPORT_FUNC(i2c_read)
-#endif	/* CFG_CMD_I2C */
+EXPORT_FUNC(i2c_probe)
+EXPORT_FUNC(usb_init)
+EXPORT_FUNC(usb_stop)
+EXPORT_FUNC(flash_write)
+EXPORT_FUNC(do_protect)
+EXPORT_FUNC(do_flerase)
diff --git a/include/exports.h b/include/exports.h
index 8f7f617..5e598aa
--- a/include/exports.h
+++ b/include/exports.h
@@ -11,22 +11,42 @@ int  getc(void);
 int  tstc(void);
 void putc(const char);
 void puts(const char*);
+int  ctrlc (void);
 void printf(const char* fmt, ...);
-void install_hdlr(int, interrupt_handler_t*, void*);
-void free_hdlr(int);
+int  sprintf(char * buf, const char *fmt, ...);
+void vprintf(const char *, va_list);
+int strcmp(const char*,const char*);
+unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base);
+int  saveenv(void);	
+char *getenv (char *name);
+void setenv (char *varname, char *varvalue);
 void *malloc(size_t);
 void free(void*);
 void udelay(unsigned long);
 unsigned long get_timer(unsigned long);
-void vprintf(const char *, va_list);
 void do_reset (void);
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base);
-char *getenv (char *name);
-void setenv (char *varname, char *varvalue);
-#if (CONFIG_COMMANDS & CFG_CMD_I2C)
+void install_hdlr(int, interrupt_handler_t*, void*);
+void free_hdlr(int);
+unsigned char in8(unsigned int);
+void out8(unsigned int, unsigned char);
+void out16(unsigned int, unsigned short);
+unsigned short in16(unsigned int);
+void out16(unsigned int, unsigned short);
+unsigned long in32(unsigned int);
+void out32(unsigned int, unsigned long);
+int netboot_common(int, void*, int , char*);
+int do_nand (void*, int, int, char*);
+void rtc_get (void*);
+int do_date (void*, int, int, char*);
 int i2c_write (uchar, uint, int , uchar* , int);
 int i2c_read (uchar, uint, int , uchar* , int);
-#endif	/* CFG_CMD_I2C */
+int i2c_probe(uchar);
+int usb_init(void);
+int usb_stop(void);
+int	flash_write (char*, ulong, ulong );
+int do_protect(void*, int, int, char*);
+int do_flerase(void*, int, int, char*);
+int xf_func_inc(int);
 
 void app_startup(char **);
 
@@ -40,7 +60,7 @@ #undef EXPORT_FUNC
 	XF_MAX
 };
 
-#define XF_VERSION	3
+#define XF_VERSION	4
 
 #if defined(CONFIG_I386)
 extern gd_t *global_data;
diff --git a/mkconfig b/mkconfig
index c3e4cea..70f2b77 100755
--- a/mkconfig
+++ b/mkconfig
@@ -72,6 +72,12 @@ echo "BOARD  = $4" >> config.mk
 
 [ "$6" ] && [ "$6" != "NULL" ] && echo "SOC    = $6" >> config.mk
 
+if [ -n "$SA" ]; then
+	echo "COMPILE_STAND_ALONE = y" >> config.mk 
+	echo "STAND_ALONE_DIR = ${SA}" >> config.mk 
+	echo "The directory \"${SA}\" will be included when u-boot is compiled" 
+	fi
+
 #
 # Create board specific header file
 #
-- 
1.4.1

