diff options
author | wdenk <wdenk> | 2003-07-24 23:38:38 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2003-07-24 23:38:38 +0000 |
commit | 27b207fd0a0941b03f27e2a82c0468b1a090c745 (patch) | |
tree | 4d339d7a2a00889f09a876425ce430be57de56e9 /examples | |
parent | 2535d60277cc295adf75cd5721dcecd840c69a63 (diff) | |
download | u-boot-imx-27b207fd0a0941b03f27e2a82c0468b1a090c745.zip u-boot-imx-27b207fd0a0941b03f27e2a82c0468b1a090c745.tar.gz u-boot-imx-27b207fd0a0941b03f27e2a82c0468b1a090c745.tar.bz2 |
* Implement new mechanism to export U-Boot's functions to standalone
applications: instead of using (PPC-specific) system calls we now
use a jump table; please see doc/README.standalone for details
* Patch by Dave Westwood, 24 Jul 2003:
added support for Unity OS (a proprietary OS)
Diffstat (limited to 'examples')
-rw-r--r-- | examples/82559_eeprom.c | 31 | ||||
-rw-r--r-- | examples/Makefile | 25 | ||||
-rw-r--r-- | examples/eepro100_eeprom.c | 20 | ||||
-rw-r--r-- | examples/hello_world.c | 21 | ||||
-rw-r--r-- | examples/mem_to_mem_idma2intr.c | 20 | ||||
-rw-r--r-- | examples/mips.lds | 56 | ||||
-rw-r--r-- | examples/sched.c | 64 | ||||
-rw-r--r-- | examples/stubs.c | 87 | ||||
-rw-r--r-- | examples/syscall.S | 114 | ||||
-rw-r--r-- | examples/timer.c | 48 |
10 files changed, 266 insertions, 220 deletions
diff --git a/examples/82559_eeprom.c b/examples/82559_eeprom.c index d66b3dd..1a121d4 100644 --- a/examples/82559_eeprom.c +++ b/examples/82559_eeprom.c @@ -22,7 +22,7 @@ #define _LINUX_STRING_H_ /* avoid unnecessary str/mem functions */ #include <common.h> -#include <syscall.h> +#include <exports.h> #include <asm/io.h> @@ -96,7 +96,7 @@ static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len) long ee_addr = ioaddr + EE_OFFSET; if (debug > 1) - mon_printf(" EEPROM op 0x%x: ", cmd); + printf(" EEPROM op 0x%x: ", cmd); outw(EE_ENB | EE_SHIFT_CLK, ee_addr); @@ -106,7 +106,7 @@ static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len) outw(dataval, ee_addr); eeprom_delay(ee_addr); if (debug > 2) - mon_printf("%X", inw(ee_addr) & 15); + printf("%X", inw(ee_addr) & 15); outw(dataval | EE_SHIFT_CLK, ee_addr); eeprom_delay(ee_addr); retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0); @@ -117,7 +117,7 @@ static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len) /* Terminate the EEPROM access. */ outw(EE_ENB & ~EE_CS, ee_addr); if (debug > 1) - mon_printf(" EEPROM result is 0x%5.5x.\n", retval); + printf(" EEPROM result is 0x%5.5x.\n", retval); return retval; } @@ -143,7 +143,7 @@ static void write_eeprom(long ioaddr, int index, int value, int addr_len) /* Poll for write finished. */ i = eeprom_busy_poll(ee_ioaddr); /* Typical 2000 ticks */ if (debug) - mon_printf(" Write finished after %d ticks.\n", i); + printf(" Write finished after %d ticks.\n", i); /* Disable programming. This command is not instantaneous, so we check for busy before the next op. */ do_eeprom_cmd(ioaddr, (0x40 << (addr_len-4)), 3 + addr_len); @@ -156,7 +156,7 @@ static int reset_eeprom(unsigned long ioaddr, unsigned char *hwaddr) int size_test; int i; - mon_printf("Resetting i82559 EEPROM @ 0x%08x ... ", ioaddr); + printf("Resetting i82559 EEPROM @ 0x%08x ... ", ioaddr); size_test = do_eeprom_cmd(ioaddr, (EE_READ_CMD << 8) << 16, 27); eeprom_addr_size = (size_test & 0xffe0000) == 0xffe0000 ? 8 : 6; @@ -177,11 +177,11 @@ static int reset_eeprom(unsigned long ioaddr, unsigned char *hwaddr) for (i = 0; i < eeprom_size; i++) if (read_eeprom(ioaddr, i, eeprom_addr_size) != eeprom[i]) { - mon_printf("failed\n"); + printf("failed\n"); return 1; } - mon_printf("done\n"); + printf("done\n"); return 0; } @@ -308,19 +308,20 @@ int main (int argc, char *argv[]) char buf[6]; int instance; + app_startup(argv); if (argc != 2) { - mon_printf ("call with base Ethernet address\n"); + printf ("call with base Ethernet address\n"); return 1; } eth_addr = gethwaddr(argv[1], buf); if (NULL == eth_addr) { - mon_printf ("Can not parse ethernet address\n"); + printf ("Can not parse ethernet address\n"); return 1; } if (eth_addr[5] & 0x01) { - mon_printf("Base Ethernet address must be even\n"); + printf("Base Ethernet address must be even\n"); } @@ -329,22 +330,22 @@ int main (int argc, char *argv[]) unsigned char mac[6]; int bar1 = read_config_dword(0, 6+instance, 0, 0x14); if (! (bar1 & 1)) { - mon_printf("ETH%d is disabled %x\n", instance, bar1); + printf("ETH%d is disabled %x\n", instance, bar1); } else { - mon_printf("ETH%d IO=0x%04x\n", instance, bar1 & ~3); + printf("ETH%d IO=0x%04x\n", instance, bar1 & ~3); } io_addr = (bar1 & (~3L)); write_config_word(0, 6+instance, 0, 4, read_config_word(0, 6+instance, 0, 4) | 1); - mon_printf("ETH%d CMD %04x\n", instance, + printf("ETH%d CMD %04x\n", instance, read_config_word(0, 6+instance, 0, 4)); memcpy(mac, eth_addr, 6); mac[5] += instance; - mon_printf("got io=%04x, ha=%02x:%02x:%02x:%02x:%02x:%02x\n", + printf("got io=%04x, ha=%02x:%02x:%02x:%02x:%02x:%02x\n", io_addr, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); reset_eeprom(io_addr, mac); diff --git a/examples/Makefile b/examples/Makefile index 9abff63..7975df5 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -21,7 +21,21 @@ # MA 02111-1307 USA # +ifeq ($(ARCH),ppc) LOAD_ADDR = 0x40000 +endif + +ifeq ($(ARCH),i386) +LOAD_ADDR = 0x40000 +endif + +ifeq ($(ARCH),arm) +LOAD_ADDR = 0xc100000 +endif + +ifeq ($(ARCH),mips) +LOAD_ADDR = 0x80200000 -T mips.lds +endif include $(TOPDIR)/config.mk @@ -38,11 +52,6 @@ SREC += sched.srec BIN += sched.bin endif -ifeq ($(ARCH),mips) -SREC = -BIN = -endif - # The following example is pretty 8xx specific... ifeq ($(CPU),mpc8xx) SREC += timer.srec @@ -62,12 +71,12 @@ endif OBJS = $(SREC:.srec=.o) -LIB = libsyscall.a -LIBAOBJS= syscall.o +LIB = libstubs.a +LIBAOBJS= ifeq ($(ARCH),ppc) LIBAOBJS+= $(ARCH)_longjmp.o $(ARCH)_setjmp.o endif -LIBCOBJS= +LIBCOBJS= stubs.o LIBOBJS = $(LIBAOBJS) $(LIBCOBJS) CPPFLAGS += -I.. diff --git a/examples/eepro100_eeprom.c b/examples/eepro100_eeprom.c index 2302003..60b937e 100644 --- a/examples/eepro100_eeprom.c +++ b/examples/eepro100_eeprom.c @@ -21,17 +21,19 @@ #define _LINUX_STRING_H_ /* avoid unnecessary str/mem functions */ #include <common.h> -#include <syscall.h> +#include <exports.h> static int reset_eeprom(unsigned long ioaddr, unsigned char *hwaddr); -int eepro100_eeprom(void) +int eepro100_eeprom(int argc, char *argv[]) { int ret = 0; unsigned char hwaddr1[6] = { 0x00, 0x00, 0x02, 0x03, 0x04, 0x05 }; unsigned char hwaddr2[6] = { 0x00, 0x00, 0x02, 0x03, 0x04, 0x06 }; + app_startup(argv); + #if defined(CONFIG_OXC) ret |= reset_eeprom(0x80000000, hwaddr1); ret |= reset_eeprom(0x81000000, hwaddr2); @@ -119,7 +121,7 @@ static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len) long ee_addr = ioaddr + EE_OFFSET; if (debug > 1) - mon_printf(" EEPROM op 0x%x: ", cmd); + printf(" EEPROM op 0x%x: ", cmd); outw(EE_ENB | EE_SHIFT_CLK, ee_addr); @@ -129,7 +131,7 @@ static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len) outw(dataval, ee_addr); eeprom_delay(ee_addr); if (debug > 2) - mon_printf("%X", inw(ee_addr) & 15); + printf("%X", inw(ee_addr) & 15); outw(dataval | EE_SHIFT_CLK, ee_addr); eeprom_delay(ee_addr); retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0); @@ -140,7 +142,7 @@ static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len) /* Terminate the EEPROM access. */ outw(EE_ENB & ~EE_CS, ee_addr); if (debug > 1) - mon_printf(" EEPROM result is 0x%5.5x.\n", retval); + printf(" EEPROM result is 0x%5.5x.\n", retval); return retval; } @@ -166,7 +168,7 @@ static void write_eeprom(long ioaddr, int index, int value, int addr_len) /* Poll for write finished. */ i = eeprom_busy_poll(ee_ioaddr); /* Typical 2000 ticks */ if (debug) - mon_printf(" Write finished after %d ticks.\n", i); + printf(" Write finished after %d ticks.\n", i); /* Disable programming. This command is not instantaneous, so we check for busy before the next op. */ do_eeprom_cmd(ioaddr, (0x40 << (addr_len-4)), 3 + addr_len); @@ -179,7 +181,7 @@ static int reset_eeprom(unsigned long ioaddr, unsigned char *hwaddr) int size_test; int i; - mon_printf("Resetting i82559 EEPROM @ 0x%08x ... ", ioaddr); + printf("Resetting i82559 EEPROM @ 0x%08lX ... ", ioaddr); size_test = do_eeprom_cmd(ioaddr, (EE_READ_CMD << 8) << 16, 27); eeprom_addr_size = (size_test & 0xffe0000) == 0xffe0000 ? 8 : 6; @@ -200,10 +202,10 @@ static int reset_eeprom(unsigned long ioaddr, unsigned char *hwaddr) for (i = 0; i < eeprom_size; i++) if (read_eeprom(ioaddr, i, eeprom_addr_size) != eeprom[i]) { - mon_printf("failed\n"); + printf("failed\n"); return 1; } - mon_printf("done\n"); + printf("done\n"); return 0; } diff --git a/examples/hello_world.c b/examples/hello_world.c index 96204c4..9317f6d 100644 --- a/examples/hello_world.c +++ b/examples/hello_world.c @@ -22,28 +22,33 @@ */ #include <common.h> -#include <syscall.h> +#include <exports.h> int hello_world (int argc, char *argv[]) { int i; - mon_printf ("Hello World\n"); + /* 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()); - mon_printf ("argc = %d\n", argc); + printf ("Hello World\n"); + + printf ("argc = %d\n", argc); for (i=0; i<=argc; ++i) { - mon_printf ("argv[%d] = \"%s\"\n", + printf ("argv[%d] = \"%s\"\n", i, argv[i] ? argv[i] : "<NULL>"); } - mon_printf ("Hit any key to exit ... "); - while (!mon_tstc()) + printf ("Hit any key to exit ... "); + while (!tstc()) ; /* consume input */ - (void) mon_getc(); + (void) getc(); - mon_printf ("\n\n"); + printf ("\n\n"); return (0); } diff --git a/examples/mem_to_mem_idma2intr.c b/examples/mem_to_mem_idma2intr.c index 3f0fd37..3a269c9 100644 --- a/examples/mem_to_mem_idma2intr.c +++ b/examples/mem_to_mem_idma2intr.c @@ -28,7 +28,7 @@ #include <common.h> -#include <syscall.h> +#include <exports.h> #define STANDALONE @@ -36,13 +36,6 @@ #include <command.h> #include <watchdog.h> #else /* Standalone app of PPCBoot */ -#include <syscall.h> -#define printf mon_printf -#define tstc mon_tstc -#define getc mon_getc -#define putc mon_putc -#define udelay mon_udelay -#define malloc mon_malloc #define WATCHDOG_RESET() { \ *(ushort *)(CFG_IMMR + 0x1000E) = 0x556c; \ *(ushort *)(CFG_IMMR + 0x1000E) = 0xaa39; \ @@ -180,8 +173,8 @@ uint dpinit_done = 0; #ifdef STANDALONE int ctrlc (void) { - if (mon_tstc()) { - switch (mon_getc ()) { + if (tstc()) { + switch (getc ()) { case 0x03: /* ^C - Control C */ return 1; default: @@ -209,19 +202,20 @@ int memcmp(const void * cs,const void * ct,size_t count) #endif /* STANDALONE */ #ifdef STANDALONE -int mem_to_mem_idma2intr (bd_t * bd, int argc, char *argv[]) +int mem_to_mem_idma2intr (int argc, char *argv[]) #else int do_idma (bd_t * bd, int argc, char *argv[]) #endif /* STANDALONE */ { int i; + app_startup(argv); dpinit_done = 0; idma_init (); DEBUG ("Installing dma handler\n"); - mon_install_hdlr (7, dmadone_handler, (void *) bdf); + install_hdlr (7, dmadone_handler, (void *) bdf); memset ((void *) 0x100000, 'a', 512); memset ((void *) 0x200000, 'b', 512); @@ -232,7 +226,7 @@ int do_idma (bd_t * bd, int argc, char *argv[]) } DEBUG ("Uninstalling dma handler\n"); - mon_free_hdlr (7); + free_hdlr (7); return 0; } diff --git a/examples/mips.lds b/examples/mips.lds new file mode 100644 index 0000000..8ed01c4 --- /dev/null +++ b/examples/mips.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk Engineering, <wd@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* +OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-bigmips") +*/ +OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradbigmips") +OUTPUT_ARCH(mips) +SECTIONS +{ + .text : + { + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .sdata : { *(.sdata) } + + _gp = ALIGN(16); + + __got_start = .; + .got : { *(.got) } + __got_end = .; + + .sdata : { *(.sdata) } + + . = ALIGN(4); + .sbss : { *(.sbss) } + .bss : { *(.bss) } +} diff --git a/examples/sched.c b/examples/sched.c index ceb5c1f..6b78f69 100644 --- a/examples/sched.c +++ b/examples/sched.c @@ -16,7 +16,7 @@ */ #include <common.h> -#include <syscall.h> +#include <exports.h> /* * Author: Arun Dharankar <ADharankar@ATTBI.Com> @@ -76,9 +76,9 @@ static uchar dbg = 0; #define PDEBUG(fmt, args...) { \ if(dbg != 0) { \ - mon_printf("[%s %d %s]: ",__FILE__,__LINE__,__FUNCTION__);\ - mon_printf(fmt, ##args); \ - mon_printf("\n"); \ + printf("[%s %d %s]: ",__FILE__,__LINE__,__FUNCTION__);\ + printf(fmt, ##args); \ + printf("\n"); \ } \ } @@ -97,41 +97,43 @@ static int thread_stop (int id); /* An example of schedular test */ #define NUMTHREADS 7 -int sched (bd_t * bd, int ac, char *av[]) +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) - mon_printf ("schedtest: Failed to create thread %d\n", i); + printf ("schedtest: Failed to create thread %d\n", i); if (j > 0) { - mon_printf ("schedtest: Created thread with id %d, name %d\n", + printf ("schedtest: Created thread with id %d, name %d\n", j, i); tid[i] = j; } } - mon_printf ("schedtest: Threads created\n"); + printf ("schedtest: Threads created\n"); - mon_printf ("sched_test: function=0x%08x\n", testthread); + printf ("sched_test: function=0x%08x\n", (unsigned)testthread); for (i = 0; i < NUMTHREADS; i++) { - mon_printf ("schedtest: Setting thread %d runnable\n", tid[i]); + printf ("schedtest: Setting thread %d runnable\n", tid[i]); thread_start (tid[i]); thread_yield (); } - mon_printf ("schedtest: Started %d threads\n", NUMTHREADS); + printf ("schedtest: Started %d threads\n", NUMTHREADS); while (1) { - mon_printf ("schedtest: Waiting for threads to complete\n"); - if (mon_tstc () && mon_getc () == 0x3) { - mon_printf ("schedtest: Aborting threads...\n"); + printf ("schedtest: Waiting for threads to complete\n"); + if (tstc () && getc () == 0x3) { + printf ("schedtest: Aborting threads...\n"); for (i = 0; i < NUMTHREADS; i++) { - mon_printf ("schedtest: Deleting thread %d\n", tid[i]); + printf ("schedtest: Deleting thread %d\n", tid[i]); thread_delete (tid[i]); } return RC_SUCCESS; @@ -139,11 +141,11 @@ int sched (bd_t * bd, int ac, char *av[]) j = -1; i = thread_join (&j); if (i == RC_FAILURE) { - mon_printf ("schedtest: No threads pending, " + printf ("schedtest: No threads pending, " "exiting schedular test\n"); return RC_SUCCESS; } - mon_printf ("schedtest: thread is %d returned %d\n", i, j); + printf ("schedtest: thread is %d returned %d\n", i, j); thread_yield (); } @@ -154,14 +156,14 @@ static int testthread (void *name) { int i; - mon_printf ("testthread: Begin executing thread, myname %d, &i=0x%08x\n", - *(int *) name, &i); + printf ("testthread: Begin executing thread, myname %d, &i=0x%08x\n", + *(int *) name, (unsigned)&i); - mon_printf ("Thread %02d, i=%d\n", *(int *) name); + printf ("Thread %02d, i=%d\n", *(int *) name, i); for (i = 0; i < 0xffff * (*(int *) name + 1); i++) { - if (mon_tstc () && mon_getc () == 0x3) { - mon_printf ("testthread: myname %d terminating.\n", + if (tstc () && getc () == 0x3) { + printf ("testthread: myname %d terminating.\n", *(int *) name); return *(int *) name + 1; } @@ -170,7 +172,7 @@ static int testthread (void *name) thread_yield (); } - mon_printf ("testthread: returning %d, i=0x%x\n", + printf ("testthread: returning %d, i=0x%x\n", *(int *) name + 1, i); return *(int *) name + 1; @@ -187,7 +189,7 @@ static void sched_init (void) current_tid = MASTER_THREAD; lthreads[current_tid].state = STATE_RUNNABLE; PDEBUG ("sched_init: master context = 0x%08x", - lthreads[current_tid].context); + (unsigned)lthreads[current_tid].context); return; } @@ -200,7 +202,8 @@ static void thread_yield (void) #define SWITCH(new) \ if(lthreads[new].state == STATE_RUNNABLE) { \ PDEBUG("thread_yield: %d match, ctx=0x%08x", \ - new, lthreads[current_tid].context); \ + new, \ + (unsigned)lthreads[current_tid].context); \ if(setjmp(lthreads[current_tid].context) == 0) { \ current_tid = new; \ PDEBUG("thread_yield: tid %d returns 0", \ @@ -260,7 +263,7 @@ static int thread_delete (int id) static void thread_launcher (void) { PDEBUG ("thread_launcher: invoking func=0x%08x", - lthreads[current_tid].func); + (unsigned)lthreads[current_tid].func); lthreads[current_tid].retval = lthreads[current_tid].func (lthreads[current_tid].arg); @@ -269,7 +272,7 @@ static void thread_launcher (void) lthreads[current_tid].state = STATE_TERMINATED; thread_yield (); - mon_printf ("thread_launcher: should NEVER get here!\n"); + printf ("thread_launcher: should NEVER get here!\n"); return; } @@ -287,7 +290,8 @@ static int thread_start (int id) if (setjmp (lthreads[current_tid].context) == 0) { lthreads[id].state = STATE_RUNNABLE; current_tid = id; - PDEBUG ("thread_start: to be stack=0%08x", lthreads[id].stack); + PDEBUG ("thread_start: to be stack=0%08x", + (unsigned)lthreads[id].stack); setctxsp (<hreads[id].stack[STK_SIZE]); thread_launcher (); } @@ -297,7 +301,7 @@ static int thread_start (int id) return RC_SUCCESS; } -#if 0 /* not used so far */ +#if 0 /* not used so far */ static int thread_stop (int id) { if (id <= MASTER_THREAD || id >= MAX_THREADS) @@ -309,7 +313,7 @@ static int thread_stop (int id) lthreads[id].state = STATE_STOPPED; return RC_SUCCESS; } -#endif /* not used so far */ +#endif /* not used so far */ static int thread_join (int *ret) { diff --git a/examples/stubs.c b/examples/stubs.c new file mode 100644 index 0000000..c0ef650 --- /dev/null +++ b/examples/stubs.c @@ -0,0 +1,87 @@ +#include <exports.h> + +#if defined(CONFIG_I386) +/* + * 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 void **jt; + +#define EXPORT_FUNC(x) \ + asm volatile ( \ +" .globl " #x "\n" \ +#x ":\n" \ +" movl %0, %%eax\n" \ +" movl jt, %%ecx\n" \ +" jmp *(%%ecx, %%eax)\n" \ + : : "i"(XF_ ## x * sizeof(void *)) : "eax", "ecx"); +#elif defined(CONFIG_PPC) +/* + * r29 holds the pointer to the global_data, r11 is a call-clobbered + * register + */ +#define EXPORT_FUNC(x) \ + asm volatile ( \ +" .globl " #x "\n" \ +#x ":\n" \ +" lwz %%r11, %0(%%r29)\n" \ +" lwz %%r11, %1(%%r11)\n" \ +" mtctr %%r11\n" \ +" bctr\n" \ + : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r11"); +#elif defined(CONFIG_ARM) +/* + * r8 holds the pointer to the global_data, ip is a call-clobbered + * register + */ +#define EXPORT_FUNC(x) \ + asm volatile ( \ +" .globl " #x "\n" \ +#x ":\n" \ +" ldr ip, [r8, %0]\n" \ +" ldr pc, [ip, %1]\n" \ + : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "ip"); +#elif defined(CONFIG_MIPS) +/* + * 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(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"(XF_ ## x * sizeof(void *)) : "t9"); +#else +#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) + */ +static void __attribute__((unused)) dummy(void) +{ +#include <_exports.h> +} + +void app_startup(char **argv) +{ +#if defined(CONFIG_I386) + /* x86 does not have a dedicated register for passing global_data */ + jt = ((gd_t *)argv[-1])->jt; +#endif +} + +#undef EXPORT_FUNC diff --git a/examples/syscall.S b/examples/syscall.S deleted file mode 100644 index f319409..0000000 --- a/examples/syscall.S +++ /dev/null @@ -1,114 +0,0 @@ -#include <ppc_asm.tmpl> -#include <ppc_defs.h> -#include <syscall.h> - -#ifdef CONFIG_ARM /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ -#warning ARM version not implemented yet /* XXXXXXXXXXXXXXXXXXXXXXXXXXXX */ - .global mon_getc - .type mon_getc,function -mon_getc: - .global mon_tstc - .type mon_tstc,function -mon_tstc: - .global mon_putc - .type mon_putc,function -mon_putc: - .global mon_puts - .type mon_puts,function -mon_puts: - .global mon_printf - .type mon_printf,function -mon_printf: - .global mon_install_hdlr - .type mon_install_hdlr,function -mon_install_hdlr: - .global mon_free_hdlr - .type mon_free_hdlr,function -mon_free_hdlr: - .global mon_malloc - .type mon_malloc,function -mon_malloc: - .global mon_free - .type mon_free,function -mon_free: - @ args = 0, pretend = 0, frame = 0 - @ frame_needed = 1, current_function_anonymous_args = 0 - mov ip, sp - stmfd sp!, {fp, ip, lr, pc} - sub fp, ip, #4 - ldmea fp, {fp, sp, pc} -#elif defined(CONFIG_MIPS)/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ -#warning MIPS version not implemented yet - .global mon_getc - .type mon_getc,function -mon_getc: - .global mon_tstc - .type mon_tstc,function -mon_tstc: - .global mon_putc - .type mon_putc,function -mon_putc: - .global mon_puts - .type mon_puts,function -mon_puts: - .global mon_printf - .type mon_printf,function -mon_printf: - .global mon_install_hdlr - .type mon_install_hdlr,function -mon_install_hdlr: - .global mon_free_hdlr - .type mon_free_hdlr,function -mon_free_hdlr: - .global mon_malloc - .type mon_malloc,function -mon_malloc: - .global mon_free - .type mon_free,function -mon_free: - -#else - -#ifdef CONFIG_I386 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ -#define SYMBOL_NAME(X) X -#define SYMBOL_NAME_LABEL(X) X##: - -#define SYSCALL(name,n) \ - .globl SYMBOL_NAME(name) ; \ -SYMBOL_NAME_LABEL(name) ; \ - movl $n, %eax ;\ - pushl %ebx; \ - pushl %ecx; \ - int $0x40 ;\ - - -#endif /* CONFIG_I386 */ - -#ifdef CONFIG_PPC -#define SYSCALL(name,n) \ - .globl name ; \ -name: ; \ - li r0,n ; \ - sc ; \ - blr -#endif /* CONFIG_PPC */ - - .text - - /* - * Make sure these functions are in the same order as they - * appear in the "include/syscall.h" header file !!! - */ - - SYSCALL(mon_getc,SYSCALL_GETC) - SYSCALL(mon_tstc,SYSCALL_TSTC) - SYSCALL(mon_putc,SYSCALL_PUTC) - SYSCALL(mon_puts,SYSCALL_PUTS) - SYSCALL(mon_printf,SYSCALL_PRINTF) - SYSCALL(mon_install_hdlr,SYSCALL_INSTALL_HDLR) - SYSCALL(mon_free_hdlr,SYSCALL_FREE_HDLR) - SYSCALL(mon_malloc,SYSCALL_MALLOC) - SYSCALL(mon_free,SYSCALL_FREE) - SYSCALL(mon_udelay,SYSCALL_UDELAY) - SYSCALL(mon_get_timer,SYSCALL_GET_TIMER) -#endif /* CONFIG_ARM XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ diff --git a/examples/timer.c b/examples/timer.c index bfe3d66..037fdfd 100644 --- a/examples/timer.c +++ b/examples/timer.c @@ -24,7 +24,7 @@ #include <common.h> #include <commproc.h> #include <mpc8xx_irq.h> -#include <syscall.h> +#include <exports.h> #undef DEBUG @@ -123,10 +123,12 @@ int timer (int argc, char *argv[]) int c; int running; + app_startup(argv); + /* Pointer to CPM Timer structure */ cpmtimerp = &((immap_t *) gd->bd->bi_immr_base)->im_cpmtimer; - mon_printf ("TIMERS=0x%x\n", (unsigned) cpmtimerp); + printf ("TIMERS=0x%x\n", (unsigned) cpmtimerp); /* Initialize pointers depending on which timer we use */ switch (TID_TIMER_ID) { @@ -166,7 +168,7 @@ int timer (int argc, char *argv[]) hwp->tgcrp = &cpmtimerp->cpmt_tgcr; - mon_printf ("Using timer %d\n" + printf ("Using timer %d\n" "tgcr @ 0x%x, tmr @ 0x%x, trr @ 0x%x," " tcr @ 0x%x, tcn @ 0x%x, ter @ 0x%x\n", TID_TIMER_ID + 1, @@ -184,24 +186,24 @@ int timer (int argc, char *argv[]) /* clear all events */ *hwp->terp = (CPMT_EVENT_CAP | CPMT_EVENT_REF); - mon_printf (usage); + printf (usage); running = 0; - while ((c = mon_getc()) != 'q') { + while ((c = getc()) != 'q') { if (c == 'b') { setPeriod (hwp, TIMER_PERIOD); /* Set period and start ticking */ /* Install interrupt handler (enable timer in CIMR) */ - mon_install_hdlr (hwp->cpm_vec, timer_handler, hwp); + install_hdlr (hwp->cpm_vec, timer_handler, hwp); - mon_printf ("Enabling timer\n"); + printf ("Enabling timer\n"); /* enable timer */ *hwp->tgcrp |= (CPMT_GCR_RST << TID_TIMER_ID); running = 1; #ifdef DEBUG - mon_printf ("tgcr=0x%x, tmr=0x%x, trr=0x%x," + printf ("tgcr=0x%x, tmr=0x%x, trr=0x%x," " tcr=0x%x, tcn=0x%x, ter=0x%x\n", *hwp->tgcrp, *hwp->tmrp, *hwp->trrp, *hwp->tcrp, *hwp->tcnp, *hwp->terp @@ -209,20 +211,20 @@ int timer (int argc, char *argv[]) #endif } else if (c == 'e') { - mon_printf ("Stopping timer\n"); + printf ("Stopping timer\n"); *hwp->tgcrp &= ~(CPMT_GCR_MASK << TID_TIMER_ID); running = 0; #ifdef DEBUG - mon_printf ("tgcr=0x%x, tmr=0x%x, trr=0x%x," + printf ("tgcr=0x%x, tmr=0x%x, trr=0x%x," " tcr=0x%x, tcn=0x%x, ter=0x%x\n", *hwp->tgcrp, *hwp->tmrp, *hwp->trrp, *hwp->tcrp, *hwp->tcnp, *hwp->terp ); #endif /* Uninstall interrupt handler */ - mon_free_hdlr (hwp->cpm_vec); + free_hdlr (hwp->cpm_vec); } else if (c == '?') { #ifdef DEBUG @@ -230,13 +232,13 @@ int timer (int argc, char *argv[]) sysconf8xx_t *siup = &((immap_t *) gd->bd->bi_immr_base)->im_siu_conf; #endif - mon_printf ("\ntgcr=0x%x, tmr=0x%x, trr=0x%x," + printf ("\ntgcr=0x%x, tmr=0x%x, trr=0x%x," " tcr=0x%x, tcn=0x%x, ter=0x%x\n", *hwp->tgcrp, *hwp->tmrp, *hwp->trrp, *hwp->tcrp, *hwp->tcnp, *hwp->terp ); #ifdef DEBUG - mon_printf ("SIUMCR=0x%08lx, SYPCR=0x%08lx," + printf ("SIUMCR=0x%08lx, SYPCR=0x%08lx," " SIMASK=0x%08lx, SIPEND=0x%08lx\n", siup->sc_siumcr, siup->sc_sypcr, @@ -244,21 +246,21 @@ int timer (int argc, char *argv[]) siup->sc_sipend ); - mon_printf ("CIMR=0x%08lx, CICR=0x%08lx, CIPR=0x%08lx\n", + printf ("CIMR=0x%08lx, CICR=0x%08lx, CIPR=0x%08lx\n", cpm_icp->cpic_cimr, cpm_icp->cpic_cicr, cpm_icp->cpic_cipr ); #endif } else { - mon_printf ("\nEnter: q - quit, b - start timer, e - stop timer, ? - get status\n"); + printf ("\nEnter: q - quit, b - start timer, e - stop timer, ? - get status\n"); } - mon_printf (usage); + printf (usage); } if (running) { - mon_printf ("Stopping timer\n"); + printf ("Stopping timer\n"); *hwp->tgcrp &= ~(CPMT_GCR_MASK << TID_TIMER_ID); - mon_free_hdlr (hwp->cpm_vec); + free_hdlr (hwp->cpm_vec); } return (0); @@ -274,11 +276,11 @@ void setPeriod (tid_8xx_cpmtimer_t *hwp, ulong interval) unsigned short prescaler; unsigned long ticks; - mon_printf ("Set interval %ld us\n", interval); + printf ("Set interval %ld us\n", interval); /* Warn if requesting longer period than possible */ if (interval > CPMT_MAX_INTERVAL) { - mon_printf ("Truncate interval %ld to maximum (%d)\n", + printf ("Truncate interval %ld to maximum (%d)\n", interval, CPMT_MAX_INTERVAL); interval = CPMT_MAX_INTERVAL; } @@ -303,7 +305,7 @@ void setPeriod (tid_8xx_cpmtimer_t *hwp, ulong interval) } #ifdef DEBUG - mon_printf ("clock/%d, prescale factor %d, reference %ld, ticks %ld\n", + printf ("clock/%d, prescale factor %d, reference %ld, ticks %ld\n", (ticks > CPMT_MAX_TICKS) ? CPMT_CLOCK_DIV : 1, CPMT_PRESCALER, (ticks / CPMT_PRESCALER), @@ -321,7 +323,7 @@ void setPeriod (tid_8xx_cpmtimer_t *hwp, ulong interval) *hwp->trrp = (unsigned short) (ticks / CPMT_PRESCALER); #ifdef DEBUG - mon_printf ("tgcr=0x%x, tmr=0x%x, trr=0x%x," + printf ("tgcr=0x%x, tmr=0x%x, trr=0x%x," " tcr=0x%x, tcn=0x%x, ter=0x%x\n", *hwp->tgcrp, *hwp->tmrp, *hwp->trrp, *hwp->tcrp, *hwp->tcnp, *hwp->terp @@ -340,7 +342,7 @@ void timer_handler (void *arg) /* printf ("** TER1=%04x ** ", *hwp->terp); */ /* just for demonstration */ - mon_printf ("."); + printf ("."); /* clear all possible events: Ref. and Cap. */ *hwp->terp = (CPMT_EVENT_CAP | CPMT_EVENT_REF); |