aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/examples
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/u-boot/examples
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/u-boot/examples')
-rw-r--r--roms/u-boot/examples/Makefile11
-rw-r--r--roms/u-boot/examples/api/.gitignore2
-rw-r--r--roms/u-boot/examples/api/Makefile71
-rw-r--r--roms/u-boot/examples/api/crt0.S78
-rw-r--r--roms/u-boot/examples/api/demo.c314
-rw-r--r--roms/u-boot/examples/api/glue.c431
-rw-r--r--roms/u-boot/examples/api/glue.h67
-rw-r--r--roms/u-boot/examples/api/libgenwrap.c50
-rw-r--r--roms/u-boot/examples/standalone/.gitignore11
-rw-r--r--roms/u-boot/examples/standalone/Makefile79
-rw-r--r--roms/u-boot/examples/standalone/README.smc91111_eeprom223
-rw-r--r--roms/u-boot/examples/standalone/atmel_df_pow2.c209
-rw-r--r--roms/u-boot/examples/standalone/hello_world.c37
-rw-r--r--roms/u-boot/examples/standalone/nds32.lds39
-rw-r--r--roms/u-boot/examples/standalone/ppc_longjmp.S66
-rw-r--r--roms/u-boot/examples/standalone/ppc_setjmp.S70
-rw-r--r--roms/u-boot/examples/standalone/sched.c354
-rw-r--r--roms/u-boot/examples/standalone/smc91111_eeprom.c372
-rw-r--r--roms/u-boot/examples/standalone/sparc.lds45
-rw-r--r--roms/u-boot/examples/standalone/stubs.c299
20 files changed, 2828 insertions, 0 deletions
diff --git a/roms/u-boot/examples/Makefile b/roms/u-boot/examples/Makefile
new file mode 100644
index 000000000..bf518bd22
--- /dev/null
+++ b/roms/u-boot/examples/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+ifdef CONFIG_EXAMPLES
+
+ifdef FTRACE
+subdir-ccflags-y += -finstrument-functions -DFTRACE
+endif
+
+subdir-y += standalone
+subdir-$(CONFIG_API) += api
+endif
diff --git a/roms/u-boot/examples/api/.gitignore b/roms/u-boot/examples/api/.gitignore
new file mode 100644
index 000000000..d7b18dcef
--- /dev/null
+++ b/roms/u-boot/examples/api/.gitignore
@@ -0,0 +1,2 @@
+demo
+demo.bin
diff --git a/roms/u-boot/examples/api/Makefile b/roms/u-boot/examples/api/Makefile
new file mode 100644
index 000000000..ca4eb1f71
--- /dev/null
+++ b/roms/u-boot/examples/api/Makefile
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2007 Semihalf
+
+# Provide symbol API_BUILD to signal that the API example is being built.
+KBUILD_CPPFLAGS += -DAPI_BUILD
+
+ifeq ($(ARCH),powerpc)
+LOAD_ADDR = 0x40000
+endif
+ifeq ($(ARCH),arm)
+LOAD_ADDR = 0x1000000
+endif
+ifeq ($(ARCH),mips)
+ifdef CONFIG_64BIT
+LOAD_ADDR = 0xffffffff80200000
+else
+LOAD_ADDR = 0x80200000
+endif
+endif
+
+# Resulting ELF and binary exectuables will be named demo and demo.bin
+extra-y = demo
+
+# Source files located in the examples/api directory
+OBJ-y += crt0.o
+OBJ-y += demo.o
+OBJ-y += glue.o
+OBJ-y += libgenwrap.o
+
+# Source files which exist outside the examples/api directory
+EXT_COBJ-y += lib/crc32.o
+EXT_COBJ-y += lib/ctype.o
+EXT_COBJ-y += lib/div64.o
+EXT_COBJ-y += lib/hexdump.o
+EXT_COBJ-y += lib/string.o
+EXT_COBJ-y += lib/time.o
+EXT_COBJ-y += lib/vsprintf.o
+EXT_COBJ-y += lib/charset.o
+EXT_COBJ-$(CONFIG_LIB_UUID) += lib/uuid.o
+EXT_SOBJ-$(CONFIG_PPC) += arch/powerpc/lib/ppcstring.o
+ifeq ($(ARCH),arm)
+EXT_SOBJ-$(CONFIG_USE_ARCH_MEMSET) += arch/arm/lib/memset.o
+endif
+
+# Create a list of object files to be compiled
+OBJS := $(OBJ-y) $(notdir $(EXT_COBJ-y) $(EXT_SOBJ-y))
+targets += $(OBJS)
+OBJS := $(addprefix $(obj)/,$(OBJS))
+
+#########################################################################
+
+quiet_cmd_link_demo = LD $@
+cmd_link_demo = $(LD) --gc-sections -Ttext $(LOAD_ADDR) -o $@ $(filter-out $(PHONY), $^) $(PLATFORM_LIBS)
+
+$(obj)/demo: $(OBJS) FORCE
+ $(call if_changed,link_demo)
+
+# demo.bin is never genrated. Is this necessary?
+OBJCOPYFLAGS_demo.bin := -O binary
+$(obj)/demo.bin: $(obj)/demo FORCE
+ $(call if_changed,objcopy)
+
+# Rule to build generic library C files
+$(addprefix $(obj)/,$(notdir $(EXT_COBJ-y))): $(obj)/%.o: lib/%.c FORCE
+ $(call cmd,force_checksrc)
+ $(call if_changed_rule,cc_o_c)
+
+# Rule to build architecture-specific library assembly files
+$(addprefix $(obj)/,$(notdir $(EXT_SOBJ-y))): $(obj)/%.o: arch/$(ARCH)/lib/%.S FORCE
+ $(call if_changed_dep,as_o_S)
diff --git a/roms/u-boot/examples/api/crt0.S b/roms/u-boot/examples/api/crt0.S
new file mode 100644
index 000000000..57bba9d85
--- /dev/null
+++ b/roms/u-boot/examples/api/crt0.S
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2007 Semihalf
+ *
+ * Written by: Rafal Jaworowski <raj@semihalf.com>
+ */
+
+#if defined(CONFIG_PPC)
+
+ .text
+ .globl _start
+_start:
+ lis %r11, search_hint@ha
+ addi %r11, %r11, search_hint@l
+ stw %r1, 0(%r11)
+ b main
+
+
+ .globl syscall
+syscall:
+ lis %r11, syscall_ptr@ha
+ addi %r11, %r11, syscall_ptr@l
+ lwz %r11, 0(%r11)
+ mtctr %r11
+ bctr
+
+#elif defined(CONFIG_ARM)
+
+ .text
+ .globl _start
+_start:
+ ldr ip, =search_hint
+ str sp, [ip]
+ b main
+
+
+ .globl syscall
+syscall:
+ ldr ip, =syscall_ptr
+ ldr pc, [ip]
+
+#elif defined(CONFIG_MIPS)
+#include <asm/asm.h>
+ .text
+ .globl __start
+ .ent __start
+__start:
+ PTR_S $sp, search_hint
+ b main
+ .end __start
+
+ .globl syscall
+ .ent syscall
+syscall:
+ PTR_S $ra, return_addr
+ PTR_L $t9, syscall_ptr
+ jalr $t9
+ nop
+ PTR_L $ra, return_addr
+ jr $ra
+ nop
+ .end syscall
+
+return_addr:
+ .align 8
+ .long 0
+#else
+#error No support for this arch!
+#endif
+
+ .globl syscall_ptr
+syscall_ptr:
+ .align 8
+ .long 0
+
+ .globl search_hint
+search_hint:
+ .long 0
diff --git a/roms/u-boot/examples/api/demo.c b/roms/u-boot/examples/api/demo.c
new file mode 100644
index 000000000..d586174ce
--- /dev/null
+++ b/roms/u-boot/examples/api/demo.c
@@ -0,0 +1,314 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2007-2008 Semihalf
+ *
+ * Written by: Rafal Jaworowski <raj@semihalf.com>
+ */
+
+#include <common.h>
+#include <env.h>
+#include <linux/types.h>
+#include <api_public.h>
+
+#include "glue.h"
+
+#define errf(fmt, args...) do { printf("ERROR @ %s(): ", __func__); printf(fmt, ##args); } while (0)
+
+#define BUF_SZ 2048
+#define WAIT_SECS 5
+
+void test_dump_buf(void *, int);
+void test_dump_di(int);
+void test_dump_si(struct sys_info *);
+void test_dump_sig(struct api_signature *);
+
+static char buf[BUF_SZ];
+
+int main(int argc, char *const argv[])
+{
+ int rv = 0, h, i, j, devs_no;
+ struct api_signature *sig = NULL;
+ ulong start, now;
+ struct device_info *di;
+ lbasize_t rlen;
+ struct display_info disinfo;
+
+ if (!api_search_sig(&sig))
+ return -1;
+
+ syscall_ptr = sig->syscall;
+ if (syscall_ptr == NULL)
+ return -2;
+
+ if (sig->version > API_SIG_VERSION)
+ return -3;
+
+ printf("API signature found @%x\n", (unsigned int)sig);
+ test_dump_sig(sig);
+
+ printf("\n*** Consumer API test ***\n");
+ printf("syscall ptr 0x%08x@%08x\n", (unsigned int)syscall_ptr,
+ (unsigned int)&syscall_ptr);
+
+ /* console activities */
+ ub_putc('B');
+
+ printf("*** Press any key to continue ***\n");
+ printf("got char 0x%x\n", ub_getc());
+
+ /* system info */
+ test_dump_si(ub_get_sys_info());
+
+ /* timing */
+ printf("\n*** Timing - wait a couple of secs ***\n");
+ start = ub_get_timer(0);
+ printf("\ntime: start %lu\n\n", start);
+ for (i = 0; i < WAIT_SECS; i++)
+ for (j = 0; j < 1000; j++)
+ ub_udelay(1000); /* wait 1 ms */
+
+ /* this is the number of milliseconds that passed from ub_get_timer(0) */
+ now = ub_get_timer(start);
+ printf("\ntime: now %lu\n\n", now);
+
+ /* enumerate devices */
+ printf("\n*** Enumerate devices ***\n");
+ devs_no = ub_dev_enum();
+
+ printf("Number of devices found: %d\n", devs_no);
+ if (devs_no == 0)
+ return -1;
+
+ printf("\n*** Show devices ***\n");
+ for (i = 0; i < devs_no; i++) {
+ test_dump_di(i);
+ printf("\n");
+ }
+
+ printf("\n*** Operations on devices ***\n");
+
+ /* test opening a device already opened */
+ h = 0;
+ if ((rv = ub_dev_open(h)) != 0) {
+ errf("open device %d error %d\n", h, rv);
+ return -1;
+ }
+ if ((rv = ub_dev_open(h)) != 0)
+ errf("open device %d error %d\n", h, rv);
+
+ ub_dev_close(h);
+
+ /* test storage */
+ printf("Trying storage devices...\n");
+ for (i = 0; i < devs_no; i++) {
+ di = ub_dev_get(i);
+
+ if (di->type & DEV_TYP_STOR)
+ break;
+
+ }
+ if (i == devs_no)
+ printf("No storage devices available\n");
+ else {
+ memset(buf, 0, BUF_SZ);
+
+ if ((rv = ub_dev_open(i)) != 0)
+ errf("open device %d error %d\n", i, rv);
+
+ else if ((rv = ub_dev_read(i, buf, 1, 0, &rlen)) != 0)
+ errf("could not read from device %d, error %d\n", i, rv);
+ else {
+ printf("Sector 0 dump (512B):\n");
+ test_dump_buf(buf, 512);
+ }
+
+ ub_dev_close(i);
+ }
+
+ /* test networking */
+ printf("Trying network devices...\n");
+ for (i = 0; i < devs_no; i++) {
+ di = ub_dev_get(i);
+
+ if (di->type == DEV_TYP_NET)
+ break;
+
+ }
+ if (i == devs_no)
+ printf("No network devices available\n");
+ else {
+ if ((rv = ub_dev_open(i)) != 0)
+ errf("open device %d error %d\n", i, rv);
+ else if ((rv = ub_dev_send(i, &buf, 2048)) != 0)
+ errf("could not send to device %d, error %d\n", i, rv);
+
+ ub_dev_close(i);
+ }
+
+ if (ub_dev_close(h) != 0)
+ errf("could not close device %d\n", h);
+
+ printf("\n*** Env vars ***\n");
+
+ printf("ethact = %s\n", ub_env_get("ethact"));
+ printf("old fileaddr = %s\n", ub_env_get("fileaddr"));
+ ub_env_set("fileaddr", "deadbeef");
+ printf("new fileaddr = %s\n", ub_env_get("fileaddr"));
+
+ const char *env = NULL;
+
+ while ((env = ub_env_enum(env)) != NULL)
+ printf("%s = %s\n", env, ub_env_get(env));
+
+ printf("\n*** Display ***\n");
+
+ if (ub_display_get_info(DISPLAY_TYPE_LCD, &disinfo)) {
+ printf("LCD info: failed\n");
+ } else {
+ printf("LCD info:\n");
+ printf(" pixel width: %d\n", disinfo.pixel_width);
+ printf(" pixel height: %d\n", disinfo.pixel_height);
+ printf(" screen rows: %d\n", disinfo.screen_rows);
+ printf(" screen cols: %d\n", disinfo.screen_cols);
+ }
+ if (ub_display_get_info(DISPLAY_TYPE_VIDEO, &disinfo)) {
+ printf("video info: failed\n");
+ } else {
+ printf("video info:\n");
+ printf(" pixel width: %d\n", disinfo.pixel_width);
+ printf(" pixel height: %d\n", disinfo.pixel_height);
+ printf(" screen rows: %d\n", disinfo.screen_rows);
+ printf(" screen cols: %d\n", disinfo.screen_cols);
+ }
+
+ printf("*** Press any key to continue ***\n");
+ printf("got char 0x%x\n", ub_getc());
+
+ /*
+ * This only clears messages on screen, not on serial port. It is
+ * equivalent to a no-op if no display is available.
+ */
+ ub_display_clear();
+
+ /* reset */
+ printf("\n*** Resetting board ***\n");
+ ub_reset();
+ printf("\nHmm, reset returned...?!\n");
+
+ return rv;
+}
+
+void test_dump_sig(struct api_signature *sig)
+{
+ printf("signature:\n");
+ printf(" version\t= %d\n", sig->version);
+ printf(" checksum\t= 0x%08x\n", sig->checksum);
+ printf(" sc entry\t= 0x%08x\n", (unsigned int)sig->syscall);
+}
+
+void test_dump_si(struct sys_info *si)
+{
+ int i;
+
+ printf("sys info:\n");
+ printf(" clkbus\t= 0x%08x\n", (unsigned int)si->clk_bus);
+ printf(" clkcpu\t= 0x%08x\n", (unsigned int)si->clk_cpu);
+ printf(" bar\t\t= 0x%08x\n", (unsigned int)si->bar);
+
+ printf("---\n");
+ for (i = 0; i < si->mr_no; i++) {
+ if (si->mr[i].flags == 0)
+ break;
+
+ printf(" start\t= 0x%08lx\n", si->mr[i].start);
+ printf(" size\t= 0x%08lx\n", si->mr[i].size);
+
+ switch(si->mr[i].flags & 0x000F) {
+ case MR_ATTR_FLASH:
+ printf(" type FLASH\n");
+ break;
+ case MR_ATTR_DRAM:
+ printf(" type DRAM\n");
+ break;
+ case MR_ATTR_SRAM:
+ printf(" type SRAM\n");
+ break;
+ default:
+ printf(" type UNKNOWN\n");
+ }
+ printf("---\n");
+ }
+}
+
+static char *test_stor_typ(int type)
+{
+ if (type & DT_STOR_IDE)
+ return "IDE";
+
+ if (type & DT_STOR_MMC)
+ return "MMC";
+
+ if (type & DT_STOR_SATA)
+ return "SATA";
+
+ if (type & DT_STOR_SCSI)
+ return "SCSI";
+
+ if (type & DT_STOR_USB)
+ return "USB";
+
+ return "Unknown";
+}
+
+void test_dump_buf(void *buf, int len)
+{
+ int i;
+ int line_counter = 0;
+ int sep_flag = 0;
+ int addr = 0;
+
+ printf("%07x:\t", addr);
+
+ for (i = 0; i < len; i++) {
+ if (line_counter++ > 15) {
+ line_counter = 0;
+ sep_flag = 0;
+ addr += 16;
+ i--;
+ printf("\n%07x:\t", addr);
+ continue;
+ }
+
+ if (sep_flag++ > 1) {
+ sep_flag = 1;
+ printf(" ");
+ }
+
+ printf("%02x", *((char *)buf++));
+ }
+
+ printf("\n");
+}
+
+void test_dump_di(int handle)
+{
+ int i;
+ struct device_info *di = ub_dev_get(handle);
+
+ printf("device info (%d):\n", handle);
+ printf(" cookie\t= 0x%08x\n", (uint32_t)di->cookie);
+ printf(" type\t\t= 0x%08x\n", di->type);
+
+ if (di->type == DEV_TYP_NET) {
+ printf(" hwaddr\t= ");
+ for (i = 0; i < 6; i++)
+ printf("%02x ", di->di_net.hwaddr[i]);
+
+ printf("\n");
+
+ } else if (di->type & DEV_TYP_STOR) {
+ printf(" type\t\t= %s\n", test_stor_typ(di->type));
+ printf(" blk size\t\t= %d\n", (unsigned int)di->di_stor.block_size);
+ printf(" blk count\t\t= %d\n", (unsigned int)di->di_stor.block_count);
+ }
+}
diff --git a/roms/u-boot/examples/api/glue.c b/roms/u-boot/examples/api/glue.c
new file mode 100644
index 000000000..91d13157a
--- /dev/null
+++ b/roms/u-boot/examples/api/glue.c
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ */
+
+#include <common.h>
+#include <env.h>
+#include <linux/types.h>
+#include <api_public.h>
+#include <u-boot/crc.h>
+
+#include "glue.h"
+
+static int valid_sig(struct api_signature *sig)
+{
+ uint32_t checksum;
+ struct api_signature s;
+
+ if (sig == NULL)
+ return 0;
+ /*
+ * Clear the checksum field (in the local copy) so as to calculate the
+ * CRC with the same initial contents as at the time when the sig was
+ * produced
+ */
+ s = *sig;
+ s.checksum = 0;
+
+ checksum = crc32(0, (unsigned char *)&s, sizeof(struct api_signature));
+
+ if (checksum != sig->checksum)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Searches for the U-Boot API signature
+ *
+ * returns 1/0 depending on found/not found result
+ */
+int api_search_sig(struct api_signature **sig)
+{
+ unsigned char *sp;
+ uint32_t search_start = 0;
+ uint32_t search_end = 0;
+
+ if (sig == NULL)
+ return 0;
+
+ if (search_hint == 0)
+ search_hint = 255 * 1024 * 1024;
+
+ search_start = search_hint & ~0x000fffff;
+ search_end = search_start + API_SEARCH_LEN - API_SIG_MAGLEN;
+
+ sp = (unsigned char *)search_start;
+ while ((sp + API_SIG_MAGLEN) < (unsigned char *)search_end) {
+ if (!memcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) {
+ *sig = (struct api_signature *)sp;
+ if (valid_sig(*sig))
+ return 1;
+ }
+ sp += API_SIG_MAGLEN;
+ }
+
+ *sig = NULL;
+ return 0;
+}
+
+/****************************************
+ *
+ * console
+ *
+ ****************************************/
+
+int ub_getc(void)
+{
+ int c;
+
+ if (!syscall(API_GETC, NULL, &c))
+ return -1;
+
+ return c;
+}
+
+int ub_tstc(void)
+{
+ int t;
+
+ if (!syscall(API_TSTC, NULL, &t))
+ return -1;
+
+ return t;
+}
+
+void ub_putc(char c)
+{
+ syscall(API_PUTC, NULL, &c);
+}
+
+void ub_puts(const char *s)
+{
+ syscall(API_PUTS, NULL, s);
+}
+
+/****************************************
+ *
+ * system
+ *
+ ****************************************/
+
+void ub_reset(void)
+{
+ syscall(API_RESET, NULL);
+}
+
+static struct mem_region mr[UB_MAX_MR];
+static struct sys_info si;
+
+struct sys_info * ub_get_sys_info(void)
+{
+ int err = 0;
+
+ memset(&si, 0, sizeof(struct sys_info));
+ si.mr = mr;
+ si.mr_no = UB_MAX_MR;
+ memset(&mr, 0, sizeof(mr));
+
+ if (!syscall(API_GET_SYS_INFO, &err, &si))
+ return NULL;
+
+ return ((err) ? NULL : &si);
+}
+
+/****************************************
+ *
+ * timing
+ *
+ ****************************************/
+
+void ub_udelay(unsigned long usec)
+{
+ syscall(API_UDELAY, NULL, &usec);
+}
+
+unsigned long ub_get_timer(unsigned long base)
+{
+ unsigned long cur;
+
+ if (!syscall(API_GET_TIMER, NULL, &cur, &base))
+ return 0;
+
+ return cur;
+}
+
+
+/****************************************************************************
+ *
+ * devices
+ *
+ * Devices are identified by handles: numbers 0, 1, 2, ..., UB_MAX_DEV-1
+ *
+ ***************************************************************************/
+
+static struct device_info devices[UB_MAX_DEV];
+
+struct device_info * ub_dev_get(int i)
+{
+ return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]);
+}
+
+/*
+ * Enumerates the devices: fills out device_info elements in the devices[]
+ * array.
+ *
+ * returns: number of devices found
+ */
+int ub_dev_enum(void)
+{
+ struct device_info *di;
+ int n = 0;
+
+ memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV);
+ di = &devices[0];
+
+ if (!syscall(API_DEV_ENUM, NULL, di))
+ return 0;
+
+ while (di->cookie != NULL) {
+
+ if (++n >= UB_MAX_DEV)
+ break;
+
+ /* take another device_info */
+ di++;
+
+ /* pass on the previous cookie */
+ di->cookie = devices[n - 1].cookie;
+
+ if (!syscall(API_DEV_ENUM, NULL, di))
+ return 0;
+ }
+
+ return n;
+}
+
+/*
+ * handle: 0-based id of the device
+ *
+ * returns: 0 when OK, err otherwise
+ */
+int ub_dev_open(int handle)
+{
+ struct device_info *di;
+ int err = 0;
+
+ if (handle < 0 || handle >= UB_MAX_DEV)
+ return API_EINVAL;
+
+ di = &devices[handle];
+
+ if (!syscall(API_DEV_OPEN, &err, di))
+ return -1;
+
+ return err;
+}
+
+int ub_dev_close(int handle)
+{
+ struct device_info *di;
+
+ if (handle < 0 || handle >= UB_MAX_DEV)
+ return API_EINVAL;
+
+ di = &devices[handle];
+ if (!syscall(API_DEV_CLOSE, NULL, di))
+ return -1;
+
+ return 0;
+}
+
+/*
+ *
+ * Validates device for read/write, it has to:
+ *
+ * - have sane handle
+ * - be opened
+ *
+ * returns: 0/1 accordingly
+ */
+static int dev_valid(int handle)
+{
+ if (handle < 0 || handle >= UB_MAX_DEV)
+ return 0;
+
+ if (devices[handle].state != DEV_STA_OPEN)
+ return 0;
+
+ return 1;
+}
+
+static int dev_stor_valid(int handle)
+{
+ if (!dev_valid(handle))
+ return 0;
+
+ if (!(devices[handle].type & DEV_TYP_STOR))
+ return 0;
+
+ return 1;
+}
+
+int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start,
+ lbasize_t *rlen)
+{
+ struct device_info *di;
+ lbasize_t act_len;
+ int err = 0;
+
+ if (!dev_stor_valid(handle))
+ return API_ENODEV;
+
+ di = &devices[handle];
+ if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))
+ return API_ESYSC;
+
+ if (!err && rlen)
+ *rlen = act_len;
+
+ return err;
+}
+
+static int dev_net_valid(int handle)
+{
+ if (!dev_valid(handle))
+ return 0;
+
+ if (devices[handle].type != DEV_TYP_NET)
+ return 0;
+
+ return 1;
+}
+
+int ub_dev_recv(int handle, void *buf, int len, int *rlen)
+{
+ struct device_info *di;
+ int err = 0, act_len;
+
+ if (!dev_net_valid(handle))
+ return API_ENODEV;
+
+ di = &devices[handle];
+ if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len))
+ return API_ESYSC;
+
+ if (!err && rlen)
+ *rlen = act_len;
+
+ return (err);
+}
+
+int ub_dev_send(int handle, void *buf, int len)
+{
+ struct device_info *di;
+ int err = 0;
+
+ if (!dev_net_valid(handle))
+ return API_ENODEV;
+
+ di = &devices[handle];
+ if (!syscall(API_DEV_WRITE, &err, di, buf, &len))
+ return API_ESYSC;
+
+ return err;
+}
+
+/****************************************
+ *
+ * env vars
+ *
+ ****************************************/
+
+char * ub_env_get(const char *name)
+{
+ char *value;
+
+ if (!syscall(API_ENV_GET, NULL, name, &value))
+ return NULL;
+
+ return value;
+}
+
+void ub_env_set(const char *name, char *value)
+{
+ syscall(API_ENV_SET, NULL, name, value);
+}
+
+static char env_name[256];
+
+const char * ub_env_enum(const char *last)
+{
+ const char *env, *str;
+ int i;
+
+ env = NULL;
+
+ /*
+ * It's OK to pass only the name piece as last (and not the whole
+ * 'name=val' string), since the API_ENUM_ENV call uses env_match()
+ * internally, which handles such case
+ */
+ if (!syscall(API_ENV_ENUM, NULL, last, &env))
+ return NULL;
+
+ if (!env)
+ /* no more env. variables to enumerate */
+ return NULL;
+
+ /* next enumerated env var */
+ memset(env_name, 0, 256);
+ for (i = 0, str = env; *str != '=' && *str != '\0';)
+ env_name[i++] = *str++;
+
+ env_name[i] = '\0';
+
+ return env_name;
+}
+
+/****************************************
+ *
+ * display
+ *
+ ****************************************/
+
+int ub_display_get_info(int type, struct display_info *di)
+{
+ int err = 0;
+
+ if (!syscall(API_DISPLAY_GET_INFO, &err, type, di))
+ return API_ESYSC;
+
+ return err;
+}
+
+int ub_display_draw_bitmap(ulong bitmap, int x, int y)
+{
+ int err = 0;
+
+ if (!syscall(API_DISPLAY_DRAW_BITMAP, &err, bitmap, x, y))
+ return API_ESYSC;
+
+ return err;
+}
+
+void ub_display_clear(void)
+{
+ syscall(API_DISPLAY_CLEAR, NULL);
+}
+
+__weak void *memcpy(void *dest, const void *src, size_t size)
+{
+ unsigned char *dptr = dest;
+ const unsigned char *ptr = src;
+ const unsigned char *end = src + size;
+
+ while (ptr < end)
+ *dptr++ = *ptr++;
+
+ return dest;
+}
diff --git a/roms/u-boot/examples/api/glue.h b/roms/u-boot/examples/api/glue.h
new file mode 100644
index 000000000..f9745604b
--- /dev/null
+++ b/roms/u-boot/examples/api/glue.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2007 Semihalf
+ *
+ * Written by: Rafal Jaworowski <raj@semihalf.com>
+ */
+
+/*
+ * This is the header file for conveniency wrapper routines (API glue)
+ */
+
+#ifndef _API_GLUE_H_
+#define _API_GLUE_H_
+
+#define API_SEARCH_LEN (3 * 1024 * 1024) /* 3MB search range */
+
+#define UB_MAX_MR 5 /* max mem regions number */
+#define UB_MAX_DEV 6 /* max devices number */
+
+extern void *syscall_ptr;
+extern uint32_t search_hint;
+
+int syscall(int, int *, ...);
+int api_search_sig(struct api_signature **sig);
+
+/*
+ * The ub_ library calls are part of the application, not U-Boot code! They
+ * are front-end wrappers that are used by the consumer application: they
+ * prepare arguments for particular syscall and jump to the low level
+ * syscall()
+ */
+
+/* console */
+int ub_getc(void);
+int ub_tstc(void);
+void ub_putc(char c);
+void ub_puts(const char *s);
+
+/* system */
+void ub_reset(void);
+struct sys_info * ub_get_sys_info(void);
+
+/* time */
+void ub_udelay(unsigned long);
+unsigned long ub_get_timer(unsigned long);
+
+/* env vars */
+char * ub_env_get(const char *name);
+void ub_env_set(const char *name, char *value);
+const char * ub_env_enum(const char *last);
+
+/* devices */
+int ub_dev_enum(void);
+int ub_dev_open(int handle);
+int ub_dev_close(int handle);
+int ub_dev_read(int handle, void *buf, lbasize_t len,
+ lbastart_t start, lbasize_t *rlen);
+int ub_dev_send(int handle, void *buf, int len);
+int ub_dev_recv(int handle, void *buf, int len, int *rlen);
+struct device_info * ub_dev_get(int);
+
+/* display */
+int ub_display_get_info(int type, struct display_info *di);
+int ub_display_draw_bitmap(ulong bitmap, int x, int y);
+void ub_display_clear(void);
+
+#endif /* _API_GLUE_H_ */
diff --git a/roms/u-boot/examples/api/libgenwrap.c b/roms/u-boot/examples/api/libgenwrap.c
new file mode 100644
index 000000000..3aa222866
--- /dev/null
+++ b/roms/u-boot/examples/api/libgenwrap.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2007 Semihalf
+ *
+ * Written by: Rafal Jaworowski <raj@semihalf.com>
+ *
+ * This is is a set of wrappers/stubs that allow to use certain routines from
+ * U-Boot's lib in the standalone app. This way way we can re-use
+ * existing code e.g. operations on strings and similar.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <hang.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <api_public.h>
+
+#include "glue.h"
+
+void putc(const char c)
+{
+ ub_putc(c);
+}
+
+void puts(const char *s)
+{
+ ub_puts(s);
+}
+
+void __udelay(unsigned long usec)
+{
+ ub_udelay(usec);
+}
+
+int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ ub_reset();
+ return 0;
+}
+
+void *malloc (size_t len)
+{
+ return NULL;
+}
+
+void hang(void)
+{
+ while (1) ;
+}
diff --git a/roms/u-boot/examples/standalone/.gitignore b/roms/u-boot/examples/standalone/.gitignore
new file mode 100644
index 000000000..6d3a6166d
--- /dev/null
+++ b/roms/u-boot/examples/standalone/.gitignore
@@ -0,0 +1,11 @@
+/atmel_df_pow2
+/hello_world
+/interrupt
+/mem_to_mem_idma2intr
+/sched
+/smc91111_eeprom
+/smc911x_eeprom
+/test_burst
+/timer
+*.bin
+*.srec
diff --git a/roms/u-boot/examples/standalone/Makefile b/roms/u-boot/examples/standalone/Makefile
new file mode 100644
index 000000000..d4be0c735
--- /dev/null
+++ b/roms/u-boot/examples/standalone/Makefile
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+extra-y := hello_world
+extra-$(CONFIG_SMC91111) += smc91111_eeprom
+extra-$(CONFIG_SPI_FLASH_ATMEL) += atmel_df_pow2
+extra-$(CONFIG_PPC) += sched
+
+#
+# Some versions of make do not handle trailing white spaces properly;
+# leading to build failures. The problem was found with GNU Make 3.80.
+# Using 'strip' as a workaround for the problem.
+#
+ELF := $(strip $(extra-y))
+
+extra-y += $(addsuffix .srec,$(extra-y)) $(addsuffix .bin,$(extra-y))
+clean-files := *.srec *.bin
+
+COBJS := $(ELF:=.o)
+
+LIB = $(obj)/libstubs.o
+
+LIBOBJS-$(CONFIG_PPC) += ppc_longjmp.o ppc_setjmp.o
+LIBOBJS-y += stubs.o
+
+targets += $(patsubst $(obj)/%,%,$(LIB)) $(COBJS) $(LIBOBJS-y)
+
+LIBOBJS := $(addprefix $(obj)/,$(LIBOBJS-y))
+ELF := $(addprefix $(obj)/,$(ELF))
+
+# For PowerPC there's no need to compile standalone applications as a
+# relocatable executable. The relocation data is not needed, and
+# also causes the entry point of the standalone application to be
+# inconsistent.
+ifeq ($(CONFIG_PPC),y)
+PLATFORM_CPPFLAGS := $(filter-out $(RELFLAGS),$(PLATFORM_CPPFLAGS))
+endif
+
+# We don't want gcc reordering functions if possible. This ensures that an
+# application's entry point will be the first function in the application's
+# source file.
+ccflags-y += $(call cc-option,-fno-toplevel-reorder)
+
+LDFLAGS_STANDALONE += -Ttext $(CONFIG_STANDALONE_LOAD_ADDR)
+
+#########################################################################
+
+quiet_cmd_link_lib = LD $@
+ cmd_link_lib = $(LD) $(ld_flags) -r -o $@ $(filter $(LIBOBJS), $^)
+
+$(LIB): $(LIBOBJS) FORCE
+ $(call if_changed,link_lib)
+
+quiet_cmd_link_elf = LD $@
+ cmd_link_elf = $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_STANDALONE) -g \
+ -o $@ -e $(SYM_PREFIX)$(@F) $< $(LIB) $(PLATFORM_LIBGCC)
+
+$(ELF): $(obj)/%: $(obj)/%.o $(LIB) FORCE
+ $(call if_changed,link_elf)
+
+$(obj)/%.srec: OBJCOPYFLAGS += -O srec
+$(obj)/%.srec: $(obj)/% FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/%.bin: OBJCOPYFLAGS += -O binary
+$(obj)/%.bin: $(obj)/% FORCE
+ $(call if_changed,objcopy)
+
+# some files can only build in ARM or THUMB2, not THUMB1
+
+ifdef CONFIG_SYS_THUMB_BUILD
+ifndef CONFIG_HAS_THUMB2
+
+CFLAGS_stubs.o := -marm
+
+endif
+endif
diff --git a/roms/u-boot/examples/standalone/README.smc91111_eeprom b/roms/u-boot/examples/standalone/README.smc91111_eeprom
new file mode 100644
index 000000000..0d8bc63f3
--- /dev/null
+++ b/roms/u-boot/examples/standalone/README.smc91111_eeprom
@@ -0,0 +1,223 @@
+This is the readme for the Das U-Boot standalone program smc91111
+
+The main purpose of this is to manage MAC addresses on platforms
+which include the SMC91111 integrated 10/100 MAC Phy, with attached
+EEPROMs.
+
+
+Contents:
+------------------------
+1. Ensuring U-Boot's MAC address can be set in hardware
+2. Running the smc91111_eeprom program
+3. Setting MAC addresses
+4. Other things you can do with this
+5. Things to be done.
+
+
+1. Ensuring U-Boot's MAC address can be set in hardware
+--------------------------------------------------------------------------
+
+On the Internet - MAC addresses are very important. Short for Media
+Access Control address, a hardware address that uniquely identifies
+each node of a network. When things are not unique - bad things
+can happen. This is why U-Boot makes it difficult to change MAC
+addresses.
+
+To find out who has a MAC address, or to purchase MAC addresses, goto
+the IEEE, at:
+http://standards.ieee.org/regauth/oui/index.shtml
+
+2. Running the smc91111_eeprom program
+---------------------------------------------------------------------
+
+After Uboot is compiled, there should be three files of interest:
+-rwxr-xr-x 1 8806 2004-10-11 14:00 smc91111_eeprom <- ELF
+-rwxr-xr-x 1 3440 2004-10-11 14:00 smc91111_eeprom.bin <- BIN
+-rwxr-xr-x 1 9524 2004-10-11 14:00 smc91111_eeprom.srec <- SREC
+
+if there is not, check the examples/Makefile, and ensure there is something
+like for your architecture:
+
+ ifeq ($(ARCH),blackfin)
+ SREC += smc91111_eeprom.srec
+ BIN += smc91111_eeprom.bin smc91111_eeprom
+ endif
+
+To load the files: there are two methods: a) serial or b) network. Since
+it is not a good idea to start doing things on the network before the
+MAC address is set, this example will do things over serial.
+
+a) Loading the elf file via the serial port
+--------------------------------------------
+Loading the elf is very easy - just ensure that the location
+you specify things to load as is not the load address specified
+in the Makefile.
+
+BOOT> loadb 0x1000000
+
+## Ready for binary (kermit) download to 0x01000000 at 57600 bps...
+
+(type CNTL-\ then C)
+(Back at local machine)
+----------------------------------------------------
+Kermit>send ~/u-boot_1.1.1/examples/smc91111_eeprom
+Kermit>connect
+
+Connecting to /dev/ttyS0, speed 57600
+ Escape character: Ctrl-\ (ASCII 28, FS): enabled
+Type the escape character followed by C to get back,
+or followed by ? to see other options.
+----------------------------------------------------
+## Total Size = 0x00002266 = 8806 Bytes
+## Start Addr = 0x01000000
+
+BOOT> bootelf 0x1000000
+
+Loading .text @ 0x00001000 (3440 bytes)
+## Starting application at 0x000010d8 ...
+
+SMC91111>
+
+b) Loading the binary file via the serial port
+-----------------------------------------------
+For many toolchains, the entry point is not the load point.
+The Load point is a hard coded address from the
+examples/Makefile. The entry point can be found by doing something
+like:
+
+ u-boot_1.1.1/examples> bfin-elf-objdump -d smc91111_eeprom |less
+
+ smc91111_eeprom: file format elf32-bfin
+
+ Disassembly of section .text:
+
+ 00001000 <smc91111_eeprom-0xd8>:
+ 1000:
+ 000010d8 <smc91111_eeprom>:
+
+You can see that the entry point (or the address that should be
+jumped to is 0x10d8). This is also the same as the entry point
+of the elf file.
+
+Now we load it to the actual load location:
+
+BOOT> loadb 0x1000
+
+## Ready for binary (kermit) download to 0x00001000 at 57600 bps...
+
+(Back at pinky.dsl-only.net)
+----------------------------------------------------
+Kermit>send /tftpboot/eeprom.bin
+Kermit>connect
+
+Connecting to /dev/ttyS0, speed 57600
+ Escape character: Ctrl-\ (ASCII 28, FS): enabled
+Type the escape character followed by C to get back,
+or followed by ? to see other options.
+----------------------------------------------------
+## Total Size = 0x00000d70 = 3440 Bytes
+## Start Addr = 0x00001000
+
+BOOT> go 0x10D8
+
+## Starting application at 0x000010D8 ...
+
+SMC91111>
+
+3. Setting MAC addresses
+--------------------------------------------------------------------------
+
+The MAC address can be stored in four locations:
+
+-Boot environmental variable in Flash <- can not change, without
+ re-flashing U-Boot.
+U-Boot environmental variable <- can not change, without
+ resetting board/U-Boot
+LAN91C111 Registers <- volatile
+LAN91C111 EEPROM <- Non-volatile
+
+If you have not activated the network, and do not have a hardcoded
+or pre-assigned MAC address in U-Boot, the environmental variables
+should be blank, and allow you to set things one time.
+
+To set the EEPROM MAC address to 12:34:56:78:9A:BC
+
+SMC91111> W E 20 3412
+
+Writing EEPROM register 20 with 3412
+SMC91111> W E 21 7856
+
+Writing EEPROM register 21 with 7856
+SMC91111> W E 22 BC9A
+
+Writing EEPROM register 22 with bc9a
+EEPROM contents copied to MAC
+SMC91111> P
+
+Current MAC Address in SMSC91111 12:34:56:78:9a:bc
+Current MAC Address in EEPROM 12:34:56:78:9a:bc
+
+(CNTRL-C to exit)
+SMC91111> ## Application terminated, rc = 0x0
+
+BOOT> reset
+U-Boot 1.1.1 (gcc version: 3.3.3)
+Release Version Beta released on Oct 10 2004 - 00:34:35
+Blackfin support by LG Soft India
+For further information please check this link http://www.blackfin.uclinux.org
+BOOT> ping 192.168.0.4
+
+Using MAC Address 12:34:56:78:9A:BC
+host 192.168.0.4 is alive
+
+
+4. Other things that you can do
+--------------------------------------------------------------------------
+After the stand alone application is running, there are a few options:
+ - P : Print the MAC
+ - D : Dump the LAN91C111 EEPROM contents
+ - M : Dump the LAN91C111 MAC contents
+ - C : Copies the MAC address from the EEPROM to the LAN91C111
+ - W : Write a register in the EEPROM or in the MAC
+
+SMC91111> P
+
+Current MAC Address in SMSC91111 12:34:56:78:9a:bc
+Current MAC Address in EEPROM 12:34:56:78:9a:bc
+
+SMC91111> D
+
+IOS2-0 000 001 002 003 004 005 006 007
+CONFIG 00:ffff 04:ffff 08:ffff 0c:ffff 10:ffff 14:ffff 18:ffff 1c:ffff
+BASE 01:ffff 05:ffff 09:ffff 0d:ffff 11:ffff 15:ffff 19:ffff 1d:ffff
+ 02:ffff 06:ffff 0a:ffff 0e:0020 12:ffff 16:ffff 1a:ffff 1e:ffff
+ 03:ffff 07:ffff 0b:ffff 0f:ffff 13:ffff 17:ffff 1b:ffff 1f:ffff
+
+20:3412 21:7856 22:bc9a 23:ffff 24:ffff 25:ffff 26:ffff 27:ffff
+28:ffff 29:ffff 2a:ffff 2b:ffff 2c:ffff 2d:ffff 2e:ffff 2f:ffff
+30:ffff 31:ffff 32:ffff 33:ffff 34:ffff 35:ffff 36:ffff 37:ffff
+38:ffff 39:ffff 3a:ffff 3b:ffff 3c:ffff 3d:ffff 3e:ffff 3f:ffff
+
+SMC91111> M
+
+ Bank0 Bank1 Bank2 Bank3
+00 0000 a0b1 3332 0000
+02 0000 1801 8000 0000
+04 0000 3412 8080 0000
+06 0000 7856 003f 0000
+08 0404 bc9a 02df 3332
+0a 0000 ffff 02df 3391
+0c 0000 1214 0004 001f
+0e 3300 3301 3302 3303
+
+SMC91111> C
+
+EEPROM contents copied to MAC
+
+SMC91111> W E 2A ABCD
+
+Writing EEPROM register 2a with abcd
+
+SMC91111> W M 14 FF00
+
+Writing MAC register bank 1, reg 04 with ff00
diff --git a/roms/u-boot/examples/standalone/atmel_df_pow2.c b/roms/u-boot/examples/standalone/atmel_df_pow2.c
new file mode 100644
index 000000000..9c74f4994
--- /dev/null
+++ b/roms/u-boot/examples/standalone/atmel_df_pow2.c
@@ -0,0 +1,209 @@
+/*
+ * atmel_df_pow2.c - convert Atmel Dataflashes to Power of 2 mode
+ *
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Licensed under the 2-clause BSD.
+ */
+
+#include <common.h>
+#include <exports.h>
+#include <spi.h>
+#include <linux/delay.h>
+
+#define CMD_ID 0x9f
+#define CMD_STAT 0xd7
+#define CMD_CFG 0x3d
+
+static int flash_cmd(struct spi_slave *slave, uchar cmd, uchar *buf, int len)
+{
+ buf[0] = cmd;
+ return spi_xfer(slave, 8 * len, buf, buf, SPI_XFER_BEGIN | SPI_XFER_END);
+}
+
+static int flash_status(struct spi_slave *slave)
+{
+ uchar buf[2];
+ if (flash_cmd(slave, CMD_STAT, buf, sizeof(buf)))
+ return -1;
+ return buf[1];
+}
+
+static int flash_set_pow2(struct spi_slave *slave)
+{
+ int ret;
+ uchar buf[4];
+
+ buf[1] = 0x2a;
+ buf[2] = 0x80;
+ buf[3] = 0xa6;
+
+ ret = flash_cmd(slave, CMD_CFG, buf, sizeof(buf));
+ if (ret)
+ return ret;
+
+ /* wait Tp, or 6 msec */
+ udelay(6000);
+
+ ret = flash_status(slave);
+ if (ret == -1)
+ return 1;
+
+ return ret & 0x1 ? 0 : 1;
+}
+
+static int flash_check(struct spi_slave *slave)
+{
+ int ret;
+ uchar buf[4];
+
+ ret = flash_cmd(slave, CMD_ID, buf, sizeof(buf));
+ if (ret)
+ return ret;
+
+ if (buf[1] != 0x1F) {
+ printf("atmel flash not found (id[0] = %#x)\n", buf[1]);
+ return 1;
+ }
+
+ if ((buf[2] >> 5) != 0x1) {
+ printf("AT45 flash not found (id[0] = %#x)\n", buf[2]);
+ return 2;
+ }
+
+ return 0;
+}
+
+static char *getline(void)
+{
+ static char buffer[100];
+ char c;
+ size_t i;
+
+ i = 0;
+ while (1) {
+ buffer[i] = '\0';
+
+ c = getc();
+
+ switch (c) {
+ case '\r': /* Enter/Return key */
+ case '\n':
+ puts("\n");
+ return buffer;
+
+ case 0x03: /* ^C - break */
+ return NULL;
+
+ case 0x5F:
+ case 0x08: /* ^H - backspace */
+ case 0x7F: /* DEL - backspace */
+ if (i) {
+ puts("\b \b");
+ i--;
+ }
+ break;
+
+ default:
+ /* Ignore control characters */
+ if (c < 0x20)
+ break;
+ /* Queue up all other characters */
+ buffer[i++] = c;
+ printf("%c", c);
+ break;
+ }
+ }
+}
+
+int atmel_df_pow2(int argc, char *const argv[])
+{
+ /* Print the ABI version */
+ app_startup(argv);
+ if (XF_VERSION != get_version()) {
+ printf("Expects ABI version %d\n", XF_VERSION);
+ printf("Actual U-Boot ABI version %lu\n", get_version());
+ printf("Can't run\n\n");
+ return 1;
+ }
+
+ while (1) {
+ struct spi_slave *slave;
+ char *line, *p;
+ int bus, cs, status;
+
+ puts("\nenter the [BUS:]CS of the SPI flash: ");
+ line = getline();
+
+ /* CTRL+C */
+ if (!line)
+ return 0;
+ if (line[0] == '\0')
+ continue;
+
+ bus = cs = simple_strtoul(line, &p, 10);
+ if (*p) {
+ if (*p == ':') {
+ ++p;
+ cs = simple_strtoul(p, &p, 10);
+ }
+ if (*p) {
+ puts("invalid format, please try again\n");
+ continue;
+ }
+ } else
+ bus = 0;
+
+ printf("\ngoing to work with dataflash at %i:%i\n", bus, cs);
+
+ /* use a low speed -- it'll work with all devices, and
+ * speed here doesn't really matter.
+ */
+ slave = spi_setup_slave(bus, cs, 1000, SPI_MODE_3);
+ if (!slave) {
+ puts("unable to setup slave\n");
+ continue;
+ }
+
+ if (spi_claim_bus(slave)) {
+ spi_free_slave(slave);
+ continue;
+ }
+
+ if (flash_check(slave)) {
+ puts("no flash found\n");
+ goto done;
+ }
+
+ status = flash_status(slave);
+ if (status == -1) {
+ puts("unable to read status register\n");
+ goto done;
+ }
+ if (status & 0x1) {
+ puts("flash is already in power-of-2 mode!\n");
+ goto done;
+ }
+
+ puts("are you sure you wish to set power-of-2 mode?\n");
+ puts("this operation is permanent and irreversible\n");
+ printf("enter YES to continue: ");
+ line = getline();
+ if (!line || strcmp(line, "YES"))
+ goto done;
+
+ if (flash_set_pow2(slave)) {
+ puts("setting pow2 mode failed\n");
+ goto done;
+ }
+
+ puts(
+ "Configuration should be updated now. You will have to\n"
+ "power cycle the part in order to finish the conversion.\n"
+ );
+
+ done:
+ spi_release_bus(slave);
+ spi_free_slave(slave);
+ }
+}
diff --git a/roms/u-boot/examples/standalone/hello_world.c b/roms/u-boot/examples/standalone/hello_world.c
new file mode 100644
index 000000000..263cd9ca0
--- /dev/null
+++ b/roms/u-boot/examples/standalone/hello_world.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <common.h>
+#include <exports.h>
+
+int hello_world(int argc, char *const argv[])
+{
+ int i;
+
+ /* Print the ABI version */
+ app_startup(argv);
+ printf ("Example expects ABI version %d\n", XF_VERSION);
+ printf ("Actual U-Boot ABI version %d\n", (int)get_version());
+
+ printf ("Hello World\n");
+
+ printf ("argc = %d\n", argc);
+
+ for (i=0; i<=argc; ++i) {
+ printf ("argv[%d] = \"%s\"\n",
+ i,
+ argv[i] ? argv[i] : "<NULL>");
+ }
+
+ printf ("Hit any key to exit ... ");
+ while (!tstc())
+ ;
+ /* consume input */
+ (void) getc();
+
+ printf ("\n\n");
+ return (0);
+}
diff --git a/roms/u-boot/examples/standalone/nds32.lds b/roms/u-boot/examples/standalone/nds32.lds
new file mode 100644
index 000000000..5a04f43c9
--- /dev/null
+++ b/roms/u-boot/examples/standalone/nds32.lds
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2011 Andes Technology Corporation
+ * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
+ * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
+ */
+
+OUTPUT_FORMAT("elf32-nds32", "elf32-nds32", "elf32-nds32")
+OUTPUT_ARCH(nds32)
+ENTRY(_start)
+SECTIONS
+{
+ . = ALIGN(4);
+ .text :
+ {
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+
+ .got : {
+ __got_start = .;
+ *(.got)
+ __got_end = .;
+ }
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss) }
+ __bss_end = .;
+
+ . = ALIGN(4);
+ .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
+
+ _end = .;
+}
diff --git a/roms/u-boot/examples/standalone/ppc_longjmp.S b/roms/u-boot/examples/standalone/ppc_longjmp.S
new file mode 100644
index 000000000..50dc2b945
--- /dev/null
+++ b/roms/u-boot/examples/standalone/ppc_longjmp.S
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/* longjmp for PowerPC.
+ Copyright (C) 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ */
+
+#include <ppc_asm.tmpl>
+
+# define JB_GPR1 0 /* Also known as the stack pointer */
+# define JB_GPR2 1
+# define JB_LR 2 /* The address we will return to */
+# define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18 in total */
+# define JB_CR 21 /* Condition code registers. */
+# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total */
+# define JB_SIZE (58*4)
+
+#define FP(x...) x
+#define FP(x...) x
+
+.globl ppc_longjmp;
+
+ppc_longjmp:
+ lwz r1,(JB_GPR1*4)(r3)
+ lwz r2,(JB_GPR2*4)(r3)
+ lwz r0,(JB_LR*4)(r3)
+ lwz r14,((JB_GPRS+0)*4)(r3)
+FP( lfd 14,((JB_FPRS+0*2)*4)(r3))
+ lwz r15,((JB_GPRS+1)*4)(r3)
+FP( lfd 15,((JB_FPRS+1*2)*4)(r3))
+ lwz r16,((JB_GPRS+2)*4)(r3)
+FP( lfd 16,((JB_FPRS+2*2)*4)(r3))
+ lwz r17,((JB_GPRS+3)*4)(r3)
+FP( lfd 17,((JB_FPRS+3*2)*4)(r3))
+ lwz r18,((JB_GPRS+4)*4)(r3)
+FP( lfd 18,((JB_FPRS+4*2)*4)(r3))
+ lwz r19,((JB_GPRS+5)*4)(r3)
+FP( lfd 19,((JB_FPRS+5*2)*4)(r3))
+ lwz r20,((JB_GPRS+6)*4)(r3)
+FP( lfd 20,((JB_FPRS+6*2)*4)(r3))
+ mtlr r0
+ lwz r21,((JB_GPRS+7)*4)(r3)
+FP( lfd 21,((JB_FPRS+7*2)*4)(r3))
+ lwz r22,((JB_GPRS+8)*4)(r3)
+FP( lfd 22,((JB_FPRS+8*2)*4)(r3))
+ lwz r0,(JB_CR*4)(r3)
+ lwz r23,((JB_GPRS+9)*4)(r3)
+FP( lfd 23,((JB_FPRS+9*2)*4)(r3))
+ lwz r24,((JB_GPRS+10)*4)(r3)
+FP( lfd 24,((JB_FPRS+10*2)*4)(r3))
+ lwz r25,((JB_GPRS+11)*4)(r3)
+FP( lfd 25,((JB_FPRS+11*2)*4)(r3))
+ mtcrf 0xFF,r0
+ lwz r26,((JB_GPRS+12)*4)(r3)
+FP( lfd 26,((JB_FPRS+12*2)*4)(r3))
+ lwz r27,((JB_GPRS+13)*4)(r3)
+FP( lfd 27,((JB_FPRS+13*2)*4)(r3))
+ lwz r28,((JB_GPRS+14)*4)(r3)
+FP( lfd 28,((JB_FPRS+14*2)*4)(r3))
+ lwz r29,((JB_GPRS+15)*4)(r3)
+FP( lfd 29,((JB_FPRS+15*2)*4)(r3))
+ lwz r30,((JB_GPRS+16)*4)(r3)
+FP( lfd 30,((JB_FPRS+16*2)*4)(r3))
+ lwz r31,((JB_GPRS+17)*4)(r3)
+FP( lfd 31,((JB_FPRS+17*2)*4)(r3))
+ mr r3,r4
+ blr
diff --git a/roms/u-boot/examples/standalone/ppc_setjmp.S b/roms/u-boot/examples/standalone/ppc_setjmp.S
new file mode 100644
index 000000000..d538fb0f2
--- /dev/null
+++ b/roms/u-boot/examples/standalone/ppc_setjmp.S
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/* setjmp for PowerPC.
+ Copyright (C) 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ */
+
+#include <ppc_asm.tmpl>
+
+# define JB_GPR1 0 /* Also known as the stack pointer */
+# define JB_GPR2 1
+# define JB_LR 2 /* The address we will return to */
+# define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18 in total */
+# define JB_CR 21 /* Condition code registers. */
+# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total */
+# define JB_SIZE (58*4)
+
+#define FP(x...) x
+
+.globl setctxsp;
+setctxsp:
+ mr r1, r3
+ blr
+
+.globl ppc_setjmp;
+ppc_setjmp:
+ stw r1,(JB_GPR1*4)(3)
+ mflr r0
+ stw r2,(JB_GPR2*4)(3)
+ stw r14,((JB_GPRS+0)*4)(3)
+FP( stfd 14,((JB_FPRS+0*2)*4)(3))
+ stw r0,(JB_LR*4)(3)
+ stw r15,((JB_GPRS+1)*4)(3)
+FP( stfd 15,((JB_FPRS+1*2)*4)(3))
+ mfcr r0
+ stw r16,((JB_GPRS+2)*4)(3)
+FP( stfd 16,((JB_FPRS+2*2)*4)(3))
+ stw r0,(JB_CR*4)(3)
+ stw r17,((JB_GPRS+3)*4)(3)
+FP( stfd 17,((JB_FPRS+3*2)*4)(3))
+ stw r18,((JB_GPRS+4)*4)(3)
+FP( stfd 18,((JB_FPRS+4*2)*4)(3))
+ stw r19,((JB_GPRS+5)*4)(3)
+FP( stfd 19,((JB_FPRS+5*2)*4)(3))
+ stw r20,((JB_GPRS+6)*4)(3)
+FP( stfd 20,((JB_FPRS+6*2)*4)(3))
+ stw r21,((JB_GPRS+7)*4)(3)
+FP( stfd 21,((JB_FPRS+7*2)*4)(3))
+ stw r22,((JB_GPRS+8)*4)(3)
+FP( stfd 22,((JB_FPRS+8*2)*4)(3))
+ stw r23,((JB_GPRS+9)*4)(3)
+FP( stfd 23,((JB_FPRS+9*2)*4)(3))
+ stw r24,((JB_GPRS+10)*4)(3)
+FP( stfd 24,((JB_FPRS+10*2)*4)(3))
+ stw r25,((JB_GPRS+11)*4)(3)
+FP( stfd 25,((JB_FPRS+11*2)*4)(3))
+ stw r26,((JB_GPRS+12)*4)(3)
+FP( stfd 26,((JB_FPRS+12*2)*4)(3))
+ stw r27,((JB_GPRS+13)*4)(3)
+FP( stfd 27,((JB_FPRS+13*2)*4)(3))
+ stw r28,((JB_GPRS+14)*4)(3)
+FP( stfd 28,((JB_FPRS+14*2)*4)(3))
+ stw r29,((JB_GPRS+15)*4)(3)
+FP( stfd 29,((JB_FPRS+15*2)*4)(3))
+ stw r30,((JB_GPRS+16)*4)(3)
+FP( stfd 30,((JB_FPRS+16*2)*4)(3))
+ stw r31,((JB_GPRS+17)*4)(3)
+FP( stfd 31,((JB_FPRS+17*2)*4)(3))
+
+ li 3, 0
+ blr
diff --git a/roms/u-boot/examples/standalone/sched.c b/roms/u-boot/examples/standalone/sched.c
new file mode 100644
index 000000000..1c5296071
--- /dev/null
+++ b/roms/u-boot/examples/standalone/sched.c
@@ -0,0 +1,354 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <common.h>
+#include <exports.h>
+
+/*
+ * Author: Arun Dharankar <ADharankar@ATTBI.Com>
+ *
+ * A very simple thread/schedular model:
+ * - only one master thread, and no parent child relation maintained
+ * - parent thread cannot be stopped or deleted
+ * - no permissions or credentials
+ * - no elaborate safety checks
+ * - cooperative multi threading
+ * - Simple round-robin scheduleing with no priorities
+ * - no metering/statistics collection
+ *
+ * Basic idea of implementing this is to allow more than one tests to
+ * execute "simultaneously".
+ *
+ * This may be modified such thread_yield may be called in syscalls, and
+ * timer interrupts.
+ */
+
+
+#define MAX_THREADS 8
+
+#define CTX_SIZE 512
+#define STK_SIZE 8*1024
+
+#define STATE_EMPTY 0
+#define STATE_RUNNABLE 1
+#define STATE_STOPPED 2
+#define STATE_TERMINATED 2
+
+#define MASTER_THREAD 0
+
+#define RC_FAILURE (-1)
+#define RC_SUCCESS (0)
+
+typedef vu_char *jmp_ctx;
+unsigned long setctxsp (vu_char *sp);
+int ppc_setjmp(jmp_ctx env);
+void ppc_longjmp(jmp_ctx env, int val);
+#define setjmp ppc_setjmp
+#define longjmp ppc_longjmp
+
+struct lthread {
+ int state;
+ int retval;
+ char stack[STK_SIZE];
+ uchar context[CTX_SIZE];
+ int (*func) (void *);
+ void *arg;
+};
+static volatile struct lthread lthreads[MAX_THREADS];
+static volatile int current_tid = MASTER_THREAD;
+
+
+static uchar dbg = 0;
+
+#define PDEBUG(fmt, args...) { \
+ if(dbg != 0) { \
+ printf("[%s %d %s]: ",__FILE__,__LINE__,__FUNCTION__);\
+ printf(fmt, ##args); \
+ printf("\n"); \
+ } \
+}
+
+static int testthread (void *);
+static void sched_init (void);
+static int thread_create (int (*func) (void *), void *arg);
+static int thread_start (int id);
+static void thread_yield (void);
+static int thread_delete (int id);
+static int thread_join (int *ret);
+
+#if 0 /* not used yet */
+static int thread_stop (int id);
+#endif /* not used yet */
+
+/* An example of schedular test */
+
+#define NUMTHREADS 7
+int sched (int ac, char *av[])
+{
+ int i, j;
+ int tid[NUMTHREADS];
+ int names[NUMTHREADS];
+
+ app_startup(av);
+
+ sched_init ();
+
+ for (i = 0; i < NUMTHREADS; i++) {
+ names[i] = i;
+ j = thread_create (testthread, (void *) &names[i]);
+ if (j == RC_FAILURE)
+ printf ("schedtest: Failed to create thread %d\n", i);
+ if (j > 0) {
+ printf ("schedtest: Created thread with id %d, name %d\n",
+ j, i);
+ tid[i] = j;
+ }
+ }
+ printf ("schedtest: Threads created\n");
+
+ printf ("sched_test: function=0x%08x\n", (unsigned)testthread);
+ for (i = 0; i < NUMTHREADS; i++) {
+ printf ("schedtest: Setting thread %d runnable\n", tid[i]);
+ thread_start (tid[i]);
+ thread_yield ();
+ }
+ printf ("schedtest: Started %d threads\n", NUMTHREADS);
+
+ while (1) {
+ printf ("schedtest: Waiting for threads to complete\n");
+ if (tstc () && getc () == 0x3) {
+ printf ("schedtest: Aborting threads...\n");
+ for (i = 0; i < NUMTHREADS; i++) {
+ printf ("schedtest: Deleting thread %d\n", tid[i]);
+ thread_delete (tid[i]);
+ }
+ return RC_SUCCESS;
+ }
+ j = -1;
+ i = thread_join (&j);
+ if (i == RC_FAILURE) {
+ printf ("schedtest: No threads pending, "
+ "exiting schedular test\n");
+ return RC_SUCCESS;
+ }
+ printf ("schedtest: thread is %d returned %d\n", i, j);
+ thread_yield ();
+ }
+
+ return RC_SUCCESS;
+}
+
+static int testthread (void *name)
+{
+ int i;
+
+ printf ("testthread: Begin executing thread, myname %d, &i=0x%08x\n",
+ *(int *) name, (unsigned)&i);
+
+ printf ("Thread %02d, i=%d\n", *(int *) name, i);
+
+ for (i = 0; i < 0xffff * (*(int *) name + 1); i++) {
+ if (tstc () && getc () == 0x3) {
+ printf ("testthread: myname %d terminating.\n",
+ *(int *) name);
+ return *(int *) name + 1;
+ }
+
+ if (i % 100 == 0)
+ thread_yield ();
+ }
+
+ printf ("testthread: returning %d, i=0x%x\n",
+ *(int *) name + 1, i);
+
+ return *(int *) name + 1;
+}
+
+
+static void sched_init (void)
+{
+ int i;
+
+ for (i = MASTER_THREAD + 1; i < MAX_THREADS; i++)
+ lthreads[i].state = STATE_EMPTY;
+
+ current_tid = MASTER_THREAD;
+ lthreads[current_tid].state = STATE_RUNNABLE;
+ PDEBUG ("sched_init: master context = 0x%08x",
+ (unsigned)lthreads[current_tid].context);
+ return;
+}
+
+static void thread_yield (void)
+{
+ static int i;
+
+ PDEBUG ("thread_yield: current tid=%d", current_tid);
+
+#define SWITCH(new) \
+ if(lthreads[new].state == STATE_RUNNABLE) { \
+ PDEBUG("thread_yield: %d match, ctx=0x%08x", \
+ new, \
+ (unsigned)lthreads[current_tid].context); \
+ if(setjmp(lthreads[current_tid].context) == 0) { \
+ current_tid = new; \
+ PDEBUG("thread_yield: tid %d returns 0", \
+ new); \
+ longjmp(lthreads[new].context, 1); \
+ } else { \
+ PDEBUG("thread_yield: tid %d returns 1", \
+ new); \
+ return; \
+ } \
+ }
+
+ for (i = current_tid + 1; i < MAX_THREADS; i++) {
+ SWITCH (i);
+ }
+
+ if (current_tid != 0) {
+ for (i = 0; i <= current_tid; i++) {
+ SWITCH (i);
+ }
+ }
+
+ PDEBUG ("thread_yield: returning from thread_yield");
+ return;
+}
+
+static int thread_create (int (*func) (void *), void *arg)
+{
+ int i;
+
+ for (i = MASTER_THREAD + 1; i < MAX_THREADS; i++) {
+ if (lthreads[i].state == STATE_EMPTY) {
+ lthreads[i].state = STATE_STOPPED;
+ lthreads[i].func = func;
+ lthreads[i].arg = arg;
+ PDEBUG ("thread_create: returns new tid %d", i);
+ return i;
+ }
+ }
+
+ PDEBUG ("thread_create: returns failure");
+ return RC_FAILURE;
+}
+
+static int thread_delete (int id)
+{
+ if (id <= MASTER_THREAD || id > MAX_THREADS)
+ return RC_FAILURE;
+
+ if (current_tid == id)
+ return RC_FAILURE;
+
+ lthreads[id].state = STATE_EMPTY;
+ return RC_SUCCESS;
+}
+
+static void thread_launcher (void)
+{
+ PDEBUG ("thread_launcher: invoking func=0x%08x",
+ (unsigned)lthreads[current_tid].func);
+
+ lthreads[current_tid].retval =
+ lthreads[current_tid].func (lthreads[current_tid].arg);
+
+ PDEBUG ("thread_launcher: tid %d terminated", current_tid);
+
+ lthreads[current_tid].state = STATE_TERMINATED;
+ thread_yield ();
+ printf ("thread_launcher: should NEVER get here!\n");
+
+ return;
+}
+
+static int thread_start (int id)
+{
+ PDEBUG ("thread_start: id=%d", id);
+ if (id <= MASTER_THREAD || id > MAX_THREADS) {
+ return RC_FAILURE;
+ }
+
+ if (lthreads[id].state != STATE_STOPPED)
+ return RC_FAILURE;
+
+ if (setjmp (lthreads[current_tid].context) == 0) {
+ lthreads[id].state = STATE_RUNNABLE;
+ current_tid = id;
+ PDEBUG ("thread_start: to be stack=0%08x",
+ (unsigned)lthreads[id].stack);
+ setctxsp ((vu_char *)&lthreads[id].stack[STK_SIZE]);
+ thread_launcher ();
+ }
+
+ PDEBUG ("thread_start: Thread id=%d started, parent returns", id);
+
+ return RC_SUCCESS;
+}
+
+#if 0 /* not used so far */
+static int thread_stop (int id)
+{
+ if (id <= MASTER_THREAD || id >= MAX_THREADS)
+ return RC_FAILURE;
+
+ if (current_tid == id)
+ return RC_FAILURE;
+
+ lthreads[id].state = STATE_STOPPED;
+ return RC_SUCCESS;
+}
+#endif /* not used so far */
+
+static int thread_join (int *ret)
+{
+ int i, j = 0;
+
+ PDEBUG ("thread_join: *ret = %d", *ret);
+
+ if (!(*ret == -1 || *ret > MASTER_THREAD || *ret < MAX_THREADS)) {
+ PDEBUG ("thread_join: invalid tid %d", *ret);
+ return RC_FAILURE;
+ }
+
+ if (*ret == -1) {
+ PDEBUG ("Checking for tid = -1");
+ while (1) {
+ /* PDEBUG("thread_join: start while-loopn"); */
+ j = 0;
+ for (i = MASTER_THREAD + 1; i < MAX_THREADS; i++) {
+ if (lthreads[i].state == STATE_TERMINATED) {
+ *ret = lthreads[i].retval;
+ lthreads[i].state = STATE_EMPTY;
+ /* PDEBUG("thread_join: returning retval %d of tid %d",
+ ret, i); */
+ return RC_SUCCESS;
+ }
+
+ if (lthreads[i].state != STATE_EMPTY) {
+ PDEBUG ("thread_join: %d used slots tid %d state=%d",
+ j, i, lthreads[i].state);
+ j++;
+ }
+ }
+ if (j == 0) {
+ PDEBUG ("thread_join: all slots empty!");
+ return RC_FAILURE;
+ }
+ /* PDEBUG("thread_join: yielding"); */
+ thread_yield ();
+ /* PDEBUG("thread_join: back from yield"); */
+ }
+ }
+
+ if (lthreads[*ret].state == STATE_TERMINATED) {
+ i = *ret;
+ *ret = lthreads[*ret].retval;
+ lthreads[*ret].state = STATE_EMPTY;
+ PDEBUG ("thread_join: returing %d for tid %d", *ret, i);
+ return RC_SUCCESS;
+ }
+
+ PDEBUG ("thread_join: thread %d is not terminated!", *ret);
+ return RC_FAILURE;
+}
diff --git a/roms/u-boot/examples/standalone/smc91111_eeprom.c b/roms/u-boot/examples/standalone/smc91111_eeprom.c
new file mode 100644
index 000000000..bf7e93064
--- /dev/null
+++ b/roms/u-boot/examples/standalone/smc91111_eeprom.c
@@ -0,0 +1,372 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2004
+ * Robin Getz rgetz@blacfin.uclinux.org
+ *
+ * Heavily borrowed from the following peoples GPL'ed software:
+ * - Wolfgang Denk, DENX Software Engineering, wd@denx.de
+ * Das U-Boot
+ * - Ladislav Michl ladis@linux-mips.org
+ * A rejected patch on the U-Boot mailing list
+ */
+
+#include <common.h>
+#include <exports.h>
+#include <linux/delay.h>
+#include "../drivers/net/smc91111.h"
+
+#ifndef SMC91111_EEPROM_INIT
+# define SMC91111_EEPROM_INIT()
+#endif
+
+#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
+#define EEPROM 0x1
+#define MAC 0x2
+#define UNKNOWN 0x4
+
+void dump_reg (struct eth_device *dev);
+void dump_eeprom (struct eth_device *dev);
+int write_eeprom_reg (struct eth_device *dev, int value, int reg);
+void copy_from_eeprom (struct eth_device *dev);
+void print_MAC (struct eth_device *dev);
+int read_eeprom_reg (struct eth_device *dev, int reg);
+void print_macaddr (struct eth_device *dev);
+
+int smc91111_eeprom(int argc, char *const argv[])
+{
+ int c, i, j, done, line, reg, value, start, what;
+ char input[50];
+
+ struct eth_device dev;
+ dev.iobase = CONFIG_SMC91111_BASE;
+
+ /* Print the ABI version */
+ app_startup (argv);
+ if (XF_VERSION != (int) get_version ()) {
+ printf ("Expects ABI version %d\n", XF_VERSION);
+ printf ("Actual U-Boot ABI version %d\n",
+ (int) get_version ());
+ printf ("Can't run\n\n");
+ return (0);
+ }
+
+ SMC91111_EEPROM_INIT();
+
+ if ((SMC_inw (&dev, BANK_SELECT) & 0xFF00) != 0x3300) {
+ printf ("Can't find SMSC91111\n");
+ return (0);
+ }
+
+ done = 0;
+ what = UNKNOWN;
+ printf ("\n");
+ while (!done) {
+ /* print the prompt */
+ printf ("SMC91111> ");
+ line = 0;
+ i = 0;
+ start = 1;
+ while (!line) {
+ /* Wait for a keystroke */
+ while (!tstc ());
+
+ c = getc ();
+ /* Make Uppercase */
+ if (c >= 'Z')
+ c -= ('a' - 'A');
+ /* printf(" |%02x| ",c); */
+
+ switch (c) {
+ case '\r': /* Enter */
+ case '\n':
+ input[i] = 0;
+ puts ("\r\n");
+ line = 1;
+ break;
+ case '\0': /* nul */
+ continue;
+
+ case 0x03: /* ^C - break */
+ input[0] = 0;
+ i = 0;
+ line = 1;
+ done = 1;
+ break;
+
+ case 0x5F:
+ case 0x08: /* ^H - backspace */
+ case 0x7F: /* DEL - backspace */
+ if (i > 0) {
+ puts ("\b \b");
+ i--;
+ }
+ break;
+ default:
+ if (start) {
+ if ((c == 'W') || (c == 'D')
+ || (c == 'M') || (c == 'C')
+ || (c == 'P')) {
+ putc (c);
+ input[i] = c;
+ if (i <= 45)
+ i++;
+ start = 0;
+ }
+ } else {
+ if ((c >= '0' && c <= '9')
+ || (c >= 'A' && c <= 'F')
+ || (c == 'E') || (c == 'M')
+ || (c == ' ')) {
+ putc (c);
+ input[i] = c;
+ if (i <= 45)
+ i++;
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ for (; i < 49; i++)
+ input[i] = 0;
+
+ switch (input[0]) {
+ case ('W'):
+ /* Line should be w reg value */
+ i = 0;
+ reg = 0;
+ value = 0;
+ /* Skip to the next space or end) */
+ while ((input[i] != ' ') && (input[i] != 0))
+ i++;
+
+ if (input[i] != 0)
+ i++;
+
+ /* Are we writing to EEPROM or MAC */
+ switch (input[i]) {
+ case ('E'):
+ what = EEPROM;
+ break;
+ case ('M'):
+ what = MAC;
+ break;
+ default:
+ what = UNKNOWN;
+ break;
+ }
+
+ /* skip to the next space or end */
+ while ((input[i] != ' ') && (input[i] != 0))
+ i++;
+ if (input[i] != 0)
+ i++;
+
+ /* Find register to write into */
+ j = 0;
+ while ((input[i] != ' ') && (input[i] != 0)) {
+ j = input[i] - 0x30;
+ if (j >= 0xA) {
+ j -= 0x07;
+ }
+ reg = (reg * 0x10) + j;
+ i++;
+ }
+
+ while ((input[i] != ' ') && (input[i] != 0))
+ i++;
+
+ if (input[i] != 0)
+ i++;
+ else
+ what = UNKNOWN;
+
+ /* Get the value to write */
+ j = 0;
+ while ((input[i] != ' ') && (input[i] != 0)) {
+ j = input[i] - 0x30;
+ if (j >= 0xA) {
+ j -= 0x07;
+ }
+ value = (value * 0x10) + j;
+ i++;
+ }
+
+ switch (what) {
+ case 1:
+ printf ("Writing EEPROM register %02x with %04x\n", reg, value);
+ write_eeprom_reg (&dev, value, reg);
+ break;
+ case 2:
+ printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value);
+ SMC_SELECT_BANK (&dev, reg >> 4);
+ SMC_outw (&dev, value, reg & 0xE);
+ break;
+ default:
+ printf ("Wrong\n");
+ break;
+ }
+ break;
+ case ('D'):
+ dump_eeprom (&dev);
+ break;
+ case ('M'):
+ dump_reg (&dev);
+ break;
+ case ('C'):
+ copy_from_eeprom (&dev);
+ break;
+ case ('P'):
+ print_macaddr (&dev);
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ return (0);
+}
+
+void copy_from_eeprom (struct eth_device *dev)
+{
+ int i;
+
+ SMC_SELECT_BANK (dev, 1);
+ SMC_outw (dev, (SMC_inw (dev, CTL_REG) & !CTL_EEPROM_SELECT) |
+ CTL_RELOAD, CTL_REG);
+ i = 100;
+ while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --i)
+ udelay(100);
+ if (i == 0) {
+ printf ("Timeout Refreshing EEPROM registers\n");
+ } else {
+ printf ("EEPROM contents copied to MAC\n");
+ }
+
+}
+
+void print_macaddr (struct eth_device *dev)
+{
+ int i, j, k, mac[6];
+
+ printf ("Current MAC Address in SMSC91111 ");
+ SMC_SELECT_BANK (dev, 1);
+ for (i = 0; i < 5; i++) {
+ printf ("%02x:", SMC_inb (dev, ADDR0_REG + i));
+ }
+
+ printf ("%02x\n", SMC_inb (dev, ADDR0_REG + 5));
+
+ i = 0;
+ for (j = 0x20; j < 0x23; j++) {
+ k = read_eeprom_reg (dev, j);
+ mac[i] = k & 0xFF;
+ i++;
+ mac[i] = k >> 8;
+ i++;
+ }
+
+ printf ("Current MAC Address in EEPROM ");
+ for (i = 0; i < 5; i++)
+ printf ("%02x:", mac[i]);
+ printf ("%02x\n", mac[5]);
+
+}
+void dump_eeprom (struct eth_device *dev)
+{
+ int j, k;
+
+ printf ("IOS2-0 ");
+ for (j = 0; j < 8; j++) {
+ printf ("%03x ", j);
+ }
+ printf ("\n");
+
+ for (k = 0; k < 4; k++) {
+ if (k == 0)
+ printf ("CONFIG ");
+ if (k == 1)
+ printf ("BASE ");
+ if ((k == 2) || (k == 3))
+ printf (" ");
+ for (j = 0; j < 0x20; j += 4) {
+ printf ("%02x:%04x ", j + k,
+ read_eeprom_reg (dev, j + k));
+ }
+ printf ("\n");
+ }
+
+ for (j = 0x20; j < 0x40; j++) {
+ if ((j & 0x07) == 0)
+ printf ("\n");
+ printf ("%02x:%04x ", j, read_eeprom_reg (dev, j));
+ }
+ printf ("\n");
+
+}
+
+int read_eeprom_reg (struct eth_device *dev, int reg)
+{
+ int timeout;
+
+ SMC_SELECT_BANK (dev, 2);
+ SMC_outw (dev, reg, PTR_REG);
+
+ SMC_SELECT_BANK (dev, 1);
+ SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
+ CTL_RELOAD, CTL_REG);
+ timeout = 100;
+ while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --timeout)
+ udelay(100);
+ if (timeout == 0) {
+ printf ("Timeout Reading EEPROM register %02x\n", reg);
+ return 0;
+ }
+
+ return SMC_inw (dev, GP_REG);
+
+}
+
+int write_eeprom_reg (struct eth_device *dev, int value, int reg)
+{
+ int timeout;
+
+ SMC_SELECT_BANK (dev, 2);
+ SMC_outw (dev, reg, PTR_REG);
+
+ SMC_SELECT_BANK (dev, 1);
+ SMC_outw (dev, value, GP_REG);
+ SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
+ CTL_STORE, CTL_REG);
+ timeout = 100;
+ while ((SMC_inw (dev, CTL_REG) & CTL_STORE) && --timeout)
+ udelay(100);
+ if (timeout == 0) {
+ printf ("Timeout Writing EEPROM register %02x\n", reg);
+ return 0;
+ }
+
+ return 1;
+
+}
+
+void dump_reg (struct eth_device *dev)
+{
+ int i, j;
+
+ printf (" ");
+ for (j = 0; j < 4; j++) {
+ printf ("Bank%i ", j);
+ }
+ printf ("\n");
+ for (i = 0; i < 0xF; i += 2) {
+ printf ("%02x ", i);
+ for (j = 0; j < 4; j++) {
+ SMC_SELECT_BANK (dev, j);
+ printf ("%04x ", SMC_inw (dev, i));
+ }
+ printf ("\n");
+ }
+}
diff --git a/roms/u-boot/examples/standalone/sparc.lds b/roms/u-boot/examples/standalone/sparc.lds
new file mode 100644
index 000000000..30719a3c4
--- /dev/null
+++ b/roms/u-boot/examples/standalone/sparc.lds
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2003, Psyent Corporation <www.psyent.com>
+ * Scott McNutt <smcnutt@psyent.com>
+ */
+
+
+OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc")
+OUTPUT_ARCH(sparc)
+ENTRY(_start)
+
+SECTIONS
+{
+ .text :
+ {
+ *(.text)
+ }
+ __text_end = .;
+
+ . = ALIGN(4);
+ .rodata :
+ {
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ }
+ __rodata_end = .;
+
+ . = ALIGN(4);
+ .data :
+ {
+ *(.data)
+ }
+
+ . = ALIGN(4);
+ __data_end = .;
+
+ __bss_start = .;
+ . = ALIGN(4);
+ .bss :
+ {
+ *(.bss)
+ }
+ . = ALIGN(4);
+ __bss_end = .;
+ _end = .;
+}
diff --git a/roms/u-boot/examples/standalone/stubs.c b/roms/u-boot/examples/standalone/stubs.c
new file mode 100644
index 000000000..5fb460454
--- /dev/null
+++ b/roms/u-boot/examples/standalone/stubs.c
@@ -0,0 +1,299 @@
+#include <common.h>
+#include <exports.h>
+#include <linux/compiler.h>
+
+struct cmd_tbl;
+
+#define FO(x) offsetof(struct jt_funcs, x)
+
+#if defined(CONFIG_X86)
+/*
+ * x86 does not have a dedicated register to store the pointer to
+ * the global_data. Thus the jump table address is stored in a
+ * global variable, but such approach does not allow for execution
+ * from flash memory. The global_data address is passed as argv[-1]
+ * to the application program.
+ */
+static struct jt_funcs *jt;
+gd_t *global_data;
+
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" movl %0, %%eax\n" \
+" movl jt, %%ecx\n" \
+" jmp *(%%ecx, %%eax)\n" \
+ : : "i"(FO(x)) : "eax", "ecx");
+#elif defined(CONFIG_PPC)
+/*
+ * r2 holds the pointer to the global_data, r11 is a call-clobbered
+ * register
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" lwz %%r11, %0(%%r2)\n" \
+" lwz %%r11, %1(%%r11)\n" \
+" mtctr %%r11\n" \
+" bctr\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r11");
+#elif defined(CONFIG_ARM)
+#ifdef CONFIG_ARM64
+/*
+ * x18 holds the pointer to the global_data, x9 is a call-clobbered
+ * register
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" ldr x9, [x18, %0]\n" \
+" ldr x9, [x9, %1]\n" \
+" br x9\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "x9");
+#else
+/*
+ * r9 holds the pointer to the global_data, ip is a call-clobbered
+ * register
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" ldr ip, [r9, %0]\n" \
+" ldr pc, [ip, %1]\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "ip");
+#endif
+#elif defined(CONFIG_MIPS)
+#ifdef CONFIG_CPU_MIPS64
+/*
+ * k0 ($26) holds the pointer to the global_data; t9 ($25) is a call-
+ * clobbered register that is also used to set gp ($26). Note that the
+ * jr instruction also executes the instruction immediately following
+ * it; however, GCC/mips generates an additional `nop' after each asm
+ * statement
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" ld $25, %0($26)\n" \
+" ld $25, %1($25)\n" \
+" jr $25\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t9");
+#else
+/*
+ * k0 ($26) holds the pointer to the global_data; t9 ($25) is a call-
+ * clobbered register that is also used to set gp ($26). Note that the
+ * jr instruction also executes the instruction immediately following
+ * it; however, GCC/mips generates an additional `nop' after each asm
+ * statement
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" lw $25, %0($26)\n" \
+" lw $25, %1($25)\n" \
+" jr $25\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t9");
+#endif
+#elif defined(CONFIG_NIOS2)
+/*
+ * gp holds the pointer to the global_data, r8 is call-clobbered
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" movhi r8, %%hi(%0)\n" \
+" ori r8, r0, %%lo(%0)\n" \
+" add r8, r8, gp\n" \
+" ldw r8, 0(r8)\n" \
+" ldw r8, %1(r8)\n" \
+" jmp r8\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "gp");
+#elif defined(CONFIG_M68K)
+/*
+ * d7 holds the pointer to the global_data, a0 is a call-clobbered
+ * register
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" move.l %%d7, %%a0\n" \
+" adda.l %0, %%a0\n" \
+" move.l (%%a0), %%a0\n" \
+" adda.l %1, %%a0\n" \
+" move.l (%%a0), %%a0\n" \
+" jmp (%%a0)\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "a0");
+#elif defined(CONFIG_MICROBLAZE)
+/*
+ * r31 holds the pointer to the global_data. r5 is a call-clobbered.
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" lwi r5, r31, %0\n" \
+" lwi r5, r5, %1\n" \
+" bra r5\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r5");
+#elif defined(CONFIG_SH)
+/*
+ * r13 holds the pointer to the global_data. r1 is a call clobbered.
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+ " .align 2\n" \
+ " .globl " #x "\n" \
+ #x ":\n" \
+ " mov r13, r1\n" \
+ " add %0, r1\n" \
+ " mov.l @r1, r2\n" \
+ " add %1, r2\n" \
+ " mov.l @r2, r1\n" \
+ " jmp @r1\n" \
+ " nop\n" \
+ " nop\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r1", "r2");
+#elif defined(CONFIG_NDS32)
+/*
+ * r16 holds the pointer to the global_data. gp is call clobbered.
+ * not support reduced register (16 GPR).
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" lwi $r16, [$gp + (%0)]\n" \
+" lwi $r16, [$r16 + (%1)]\n" \
+" jr $r16\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "$r16");
+#elif defined(CONFIG_RISCV)
+/*
+ * gp holds the pointer to the global_data. t0 is call clobbered.
+ */
+#ifdef CONFIG_ARCH_RV64I
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" ld t0, %0(gp)\n" \
+" ld t0, %1(t0)\n" \
+" jr t0\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t0");
+#else
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" lw t0, %0(gp)\n" \
+" lw t0, %1(t0)\n" \
+" jr t0\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t0");
+#endif
+#elif defined(CONFIG_ARC)
+/*
+ * r25 holds the pointer to the global_data. r10 is call clobbered.
+ */
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile( \
+" .align 4\n" \
+" .globl " #x "\n" \
+#x ":\n" \
+" ld r10, [r25, %0]\n" \
+" ld r10, [r10, %1]\n" \
+" j [r10]\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r10");
+#elif defined(CONFIG_XTENSA)
+/*
+ * Global data ptr is in global_data, jump table ptr is in jt.
+ * Windowed ABI: Jump just past 'entry' in target and adjust stack frame
+ * (extract stack frame size from target 'entry' instruction).
+ */
+
+static void **jt;
+
+#if defined(__XTENSA_CALL0_ABI__)
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .extern jt\n" \
+" .globl " #x "\n" \
+" .align 4\n" \
+#x ":\n" \
+" l32i a8, %0, 0\n" \
+" l32i a8, a8, %1\n" \
+" jx a8\n" \
+ : : "r"(jt), "i" (FO(x)) : "a8");
+#elif defined(__XTENSA_WINDOWED_ABI__)
+#if XCHAL_HAVE_BE
+# define SFT "8"
+#else
+# define SFT "12"
+#endif
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .extern jt\n" \
+" .globl " #x "\n" \
+" .align 4\n" \
+#x ":\n" \
+" entry sp, 16\n" \
+" l32i a8, %0, 0\n" \
+" l32i a8, a8, %1\n" \
+" l32i a9, a8, 0\n" \
+" extui a9, a9, " SFT ", 12\n" \
+" subx8 a9, a9, sp\n" \
+" movi a10, 16\n" \
+" sub a9, a10, a9\n" \
+" movsp sp, a9\n" \
+" addi a8, a8, 3\n" \
+" jx a8\n" \
+ : : "r"(jt), "i" (FO(x)) : "a8", "a9", "a10");
+#else
+#error Unsupported Xtensa ABI
+#endif
+#else
+/*" addi $sp, $sp, -24\n" \
+" br $r16\n" \*/
+
+#error stubs definition missing for this architecture
+#endif
+
+/* This function is necessary to prevent the compiler from
+ * generating prologue/epilogue, preparing stack frame etc.
+ * The stub functions are special, they do not use the stack
+ * frame passed to them, but pass it intact to the actual
+ * implementation. On the other hand, asm() statements with
+ * arguments can be used only inside the functions (gcc limitation)
+ */
+#if GCC_VERSION < 30400
+static
+#endif /* GCC_VERSION */
+void __attribute__((unused)) dummy(void)
+{
+#include <_exports.h>
+}
+
+#include <asm/sections.h>
+
+void app_startup(char * const *argv)
+{
+ char *cp = __bss_start;
+
+ /* Zero out BSS */
+ while (cp < _end)
+ *cp++ = 0;
+
+#if defined(CONFIG_X86)
+ /* x86 does not have a dedicated register for passing global_data */
+ global_data = (gd_t *)argv[-1];
+ jt = global_data->jt;
+#endif
+}
+
+#undef EXPORT_FUNC