diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/config.mk | 20 | ||||
-rw-r--r-- | arch/mips/cpu/mips32/config.mk | 19 | ||||
-rw-r--r-- | arch/mips/cpu/xburst/config.mk | 5 | ||||
-rw-r--r-- | arch/mips/cpu/xburst/cpu.c | 2 | ||||
-rw-r--r-- | arch/mips/cpu/xburst/timer.c | 12 | ||||
-rw-r--r-- | arch/mips/lib/Makefile | 20 | ||||
-rw-r--r-- | arch/mips/lib/ashldi3.c | 25 | ||||
-rw-r--r-- | arch/mips/lib/ashrdi3.c | 27 | ||||
-rw-r--r-- | arch/mips/lib/libgcc.h | 25 | ||||
-rw-r--r-- | arch/mips/lib/lshrdi3.c | 25 |
10 files changed, 151 insertions, 29 deletions
diff --git a/arch/mips/config.mk b/arch/mips/config.mk index 6ab8acd..de9140b 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -23,7 +23,21 @@ CROSS_COMPILE ?= mips_4KC- -CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds +# Handle special prefix in ELDK 4.0 toolchain +ifneq (,$(findstring 4KCle,$(CROSS_COMPILE))) +ENDIANNESS := -EL +endif + +ifdef CONFIG_SYS_LITTLE_ENDIAN +ENDIANNESS := -EL +endif + +ifdef CONFIG_SYS_BIG_ENDIAN +ENDIANNESS := -EB +endif + +# Default to EB if no endianess is configured +ENDIANNESS ?= -EB PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__ @@ -47,8 +61,8 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__ # On the other hand, we want PIC in the U-Boot code to relocate it from ROM # to RAM. $28 is always used as gp. # -PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic +PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS) PLATFORM_CPPFLAGS += -msoft-float -PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib +PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS) PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections LDFLAGS_FINAL += --gc-sections diff --git a/arch/mips/cpu/mips32/config.mk b/arch/mips/cpu/mips32/config.mk index a1cd590..481e984 100644 --- a/arch/mips/cpu/mips32/config.mk +++ b/arch/mips/cpu/mips32/config.mk @@ -29,21 +29,6 @@ # MIPSFLAGS := -march=mips32r2 -# Handle special prefix in ELDK 4.0 toolchain -ifneq (,$(findstring 4KCle,$(CROSS_COMPILE))) -ENDIANNESS := -EL -endif +PLATFORM_CPPFLAGS += $(MIPSFLAGS) -ifdef CONFIG_SYS_LITTLE_ENDIAN -ENDIANNESS := -EL -endif - -ifdef CONFIG_SYS_BIG_ENDIAN -ENDIANNESS := -EB -endif - -# Default to EB if no endianess is configured -ENDIANNESS ?= -EB - -PLATFORM_CPPFLAGS += $(MIPSFLAGS) $(ENDIANNESS) -PLATFORM_LDFLAGS += $(ENDIANNESS) +CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds diff --git a/arch/mips/cpu/xburst/config.mk b/arch/mips/cpu/xburst/config.mk index bce0c1b..1536746 100644 --- a/arch/mips/cpu/xburst/config.mk +++ b/arch/mips/cpu/xburst/config.mk @@ -20,5 +20,6 @@ # MA 02111-1307 USA # -PLATFORM_CPPFLAGS += -march=mips32 -EL -PLATFORM_LDFLAGS += -EL +PLATFORM_CPPFLAGS += -march=mips32 + +CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c index e976341..ddcbfaa 100644 --- a/arch/mips/cpu/xburst/cpu.c +++ b/arch/mips/cpu/xburst/cpu.c @@ -62,7 +62,7 @@ void __attribute__((weak)) _machine_restart(void) writew(100, &wdt->tdr); /* wdt_set_data(100) */ writew(0, &wdt->tcnt); /* wdt_set_count(0); */ - writew(TCU_TSSR_WDTSC, &tcu->tscr); /* tcu_start_wdt_clock */ + writel(TCU_TSSR_WDTSC, &tcu->tscr); /* tcu_start_wdt_clock */ writeb(readb(&wdt->tcer) | WDT_TCER_TCEN, &wdt->tcer); /* wdt start */ while (1) diff --git a/arch/mips/cpu/xburst/timer.c b/arch/mips/cpu/xburst/timer.c index de6f5da..b6b3855 100644 --- a/arch/mips/cpu/xburst/timer.c +++ b/arch/mips/cpu/xburst/timer.c @@ -34,13 +34,13 @@ static struct jz4740_tcu *tcu = (struct jz4740_tcu *)JZ4740_TCU_BASE; void reset_timer_masked(void) { /* reset time */ - gd->lastinc = readw(&tcu->tcnt0); + gd->lastinc = readl(&tcu->tcnt0); gd->tbl = 0; } ulong get_timer_masked(void) { - ulong now = readw(&tcu->tcnt0); + ulong now = readl(&tcu->tcnt0); if (gd->lastinc <= now) gd->tbl += now - gd->lastinc; /* normal mode */ @@ -83,11 +83,11 @@ void udelay_masked(unsigned long usec) int timer_init(void) { - writew(TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN, &tcu->tcsr0); + writel(TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN, &tcu->tcsr0); - writew(0, &tcu->tcnt0); - writew(0, &tcu->tdhr0); - writew(TIMER_FDATA, &tcu->tdfr0); + writel(0, &tcu->tcnt0); + writel(0, &tcu->tdhr0); + writel(TIMER_FDATA, &tcu->tdfr0); /* mask irqs */ writel((1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)), &tcu->tmsr); diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 9244f31..967e98a 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -25,6 +25,13 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).o +## Build a couple of necessary functions into a private libgcc +LIBGCC = $(obj)libgcc.o +GLSOBJS += ashldi3.o +GLSOBJS += ashrdi3.o +GLSOBJS += lshrdi3.o +LGOBJS := $(addprefix $(obj),$(GLSOBJS)) + SOBJS-y += COBJS-y += board.o @@ -37,9 +44,22 @@ endif SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) +# Always build libmips.o +TARGETS := $(LIB) + +# Build private libgcc only when asked for +ifdef USE_PRIVATE_LIBGCC +TARGETS += $(LIBGCC) +endif + +all: $(TARGETS) + $(LIB): $(obj).depend $(OBJS) $(call cmd_link_o_target, $(OBJS)) +$(LIBGCC): $(obj).depend $(LGOBJS) + $(call cmd_link_o_target, $(LGOBJS)) + ######################################################################### # defines $(obj).depend target diff --git a/arch/mips/lib/ashldi3.c b/arch/mips/lib/ashldi3.c new file mode 100644 index 0000000..9b50d86 --- /dev/null +++ b/arch/mips/lib/ashldi3.c @@ -0,0 +1,25 @@ +#include "libgcc.h" + +long long __ashldi3(long long u, word_type b) +{ + DWunion uu, w; + word_type bm; + + if (b == 0) + return u; + + uu.ll = u; + bm = 32 - b; + + if (bm <= 0) { + w.s.low = 0; + w.s.high = (unsigned int) uu.s.low << -bm; + } else { + const unsigned int carries = (unsigned int) uu.s.low >> bm; + + w.s.low = (unsigned int) uu.s.low << b; + w.s.high = ((unsigned int) uu.s.high << b) | carries; + } + + return w.ll; +} diff --git a/arch/mips/lib/ashrdi3.c b/arch/mips/lib/ashrdi3.c new file mode 100644 index 0000000..f30359b --- /dev/null +++ b/arch/mips/lib/ashrdi3.c @@ -0,0 +1,27 @@ +#include "libgcc.h" + +long long __ashrdi3(long long u, word_type b) +{ + DWunion uu, w; + word_type bm; + + if (b == 0) + return u; + + uu.ll = u; + bm = 32 - b; + + if (bm <= 0) { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = + uu.s.high >> 31; + w.s.low = uu.s.high >> -bm; + } else { + const unsigned int carries = (unsigned int) uu.s.high << bm; + + w.s.high = uu.s.high >> b; + w.s.low = ((unsigned int) uu.s.low >> b) | carries; + } + + return w.ll; +} diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h new file mode 100644 index 0000000..05909d5 --- /dev/null +++ b/arch/mips/lib/libgcc.h @@ -0,0 +1,25 @@ +#ifndef __ASM_LIBGCC_H +#define __ASM_LIBGCC_H + +#include <asm/byteorder.h> + +typedef int word_type __attribute__ ((mode (__word__))); + +#ifdef __BIG_ENDIAN +struct DWstruct { + int high, low; +}; +#elif defined(__LITTLE_ENDIAN) +struct DWstruct { + int low, high; +}; +#else +#error I feel sick. +#endif + +typedef union { + struct DWstruct s; + long long ll; +} DWunion; + +#endif /* __ASM_LIBGCC_H */ diff --git a/arch/mips/lib/lshrdi3.c b/arch/mips/lib/lshrdi3.c new file mode 100644 index 0000000..bb340ac --- /dev/null +++ b/arch/mips/lib/lshrdi3.c @@ -0,0 +1,25 @@ +#include "libgcc.h" + +long long __lshrdi3(long long u, word_type b) +{ + DWunion uu, w; + word_type bm; + + if (b == 0) + return u; + + uu.ll = u; + bm = 32 - b; + + if (bm <= 0) { + w.s.high = 0; + w.s.low = (unsigned int) uu.s.high >> -bm; + } else { + const unsigned int carries = (unsigned int) uu.s.high << bm; + + w.s.high = (unsigned int) uu.s.high >> b; + w.s.low = ((unsigned int) uu.s.low >> b) | carries; + } + + return w.ll; +} |