summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
authorTom Rini <trini@ti.com>2012-10-17 08:57:13 -0700
committerTom Rini <trini@ti.com>2012-10-17 08:57:13 -0700
commitd1ff690612415470a681787c029803952142043d (patch)
tree09a7a42be56797aa57abefc8f464bffa1ecb16da /arch/mips
parentff04f6d1224d8952b566b8671222151495883073 (diff)
parent6b2eba1b7cd661fc6b2b0e0d4d039d1c299e2e07 (diff)
downloadu-boot-imx-d1ff690612415470a681787c029803952142043d.zip
u-boot-imx-d1ff690612415470a681787c029803952142043d.tar.gz
u-boot-imx-d1ff690612415470a681787c029803952142043d.tar.bz2
Merge branch 'master' of git://git.denx.de/u-boot-mips
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/cpu/mips32/cache.S10
-rw-r--r--arch/mips/cpu/mips32/cpu.c8
-rw-r--r--arch/mips/cpu/mips64/Makefile45
-rw-r--r--arch/mips/cpu/mips64/cache.S229
-rw-r--r--arch/mips/cpu/mips64/config.mk40
-rw-r--r--arch/mips/cpu/mips64/cpu.c111
-rw-r--r--arch/mips/cpu/mips64/interrupts.c34
-rw-r--r--arch/mips/cpu/mips64/start.S256
-rw-r--r--arch/mips/cpu/mips64/time.c87
-rw-r--r--arch/mips/cpu/xburst/cpu.c12
-rw-r--r--arch/mips/cpu/xburst/start.S4
-rw-r--r--arch/mips/include/asm/addrspace.h2
-rw-r--r--arch/mips/include/asm/asm.h2
-rw-r--r--arch/mips/include/asm/cacheops.h82
-rw-r--r--arch/mips/include/asm/io.h16
-rw-r--r--arch/mips/include/asm/posix_types.h6
16 files changed, 884 insertions, 60 deletions
diff --git a/arch/mips/cpu/mips32/cache.S b/arch/mips/cpu/mips32/cache.S
index e683e8b..64dfad0 100644
--- a/arch/mips/cpu/mips32/cache.S
+++ b/arch/mips/cpu/mips32/cache.S
@@ -85,17 +85,17 @@ LEAF(mips_init_icache)
/* clear tag to invalidate */
PTR_LI t0, INDEX_BASE
PTR_ADDU t1, t0, a1
-1: cache_op Index_Store_Tag_I t0
+1: cache_op INDEX_STORE_TAG_I t0
PTR_ADDU t0, a2
bne t0, t1, 1b
/* fill once, so data field parity is correct */
PTR_LI t0, INDEX_BASE
-2: cache_op Fill t0
+2: cache_op FILL t0
PTR_ADDU t0, a2
bne t0, t1, 2b
/* invalidate again - prudent but not strictly neccessary */
PTR_LI t0, INDEX_BASE
-1: cache_op Index_Store_Tag_I t0
+1: cache_op INDEX_STORE_TAG_I t0
PTR_ADDU t0, a2
bne t0, t1, 1b
9: jr ra
@@ -110,7 +110,7 @@ LEAF(mips_init_dcache)
/* clear all tags */
PTR_LI t0, INDEX_BASE
PTR_ADDU t1, t0, a1
-1: cache_op Index_Store_Tag_D t0
+1: cache_op INDEX_STORE_TAG_D t0
PTR_ADDU t0, a2
bne t0, t1, 1b
/* load from each line (in cached space) */
@@ -120,7 +120,7 @@ LEAF(mips_init_dcache)
bne t0, t1, 2b
/* clear all tags */
PTR_LI t0, INDEX_BASE
-1: cache_op Index_Store_Tag_D t0
+1: cache_op INDEX_STORE_TAG_D t0
PTR_ADDU t0, a2
bne t0, t1, 1b
9: jr ra
diff --git a/arch/mips/cpu/mips32/cpu.c b/arch/mips/cpu/mips32/cpu.c
index 7b49e1b..50bb248 100644
--- a/arch/mips/cpu/mips32/cpu.c
+++ b/arch/mips/cpu/mips32/cpu.c
@@ -61,8 +61,8 @@ void flush_cache(ulong start_addr, ulong size)
return;
while (1) {
- cache_op(Hit_Writeback_Inv_D, addr);
- cache_op(Hit_Invalidate_I, addr);
+ cache_op(HIT_WRITEBACK_INV_D, addr);
+ cache_op(HIT_INVALIDATE_I, addr);
if (addr == aend)
break;
addr += lsize;
@@ -76,7 +76,7 @@ void flush_dcache_range(ulong start_addr, ulong stop)
unsigned long aend = (stop - 1) & ~(lsize - 1);
while (1) {
- cache_op(Hit_Writeback_Inv_D, addr);
+ cache_op(HIT_WRITEBACK_INV_D, addr);
if (addr == aend)
break;
addr += lsize;
@@ -90,7 +90,7 @@ void invalidate_dcache_range(ulong start_addr, ulong stop)
unsigned long aend = (stop - 1) & ~(lsize - 1);
while (1) {
- cache_op(Hit_Invalidate_D, addr);
+ cache_op(HIT_INVALIDATE_D, addr);
if (addr == aend)
break;
addr += lsize;
diff --git a/arch/mips/cpu/mips64/Makefile b/arch/mips/cpu/mips64/Makefile
new file mode 100644
index 0000000..be38664
--- /dev/null
+++ b/arch/mips/cpu/mips64/Makefile
@@ -0,0 +1,45 @@
+#
+# (C) Copyright 2003-2006
+# Wolfgang Denk, DENX Software 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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(CPU).o
+
+START = start.o
+COBJS-y = cpu.o interrupts.o time.o cache.o
+
+SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
diff --git a/arch/mips/cpu/mips64/cache.S b/arch/mips/cpu/mips64/cache.S
new file mode 100644
index 0000000..036f035
--- /dev/null
+++ b/arch/mips/cpu/mips64/cache.S
@@ -0,0 +1,229 @@
+/*
+ * Cache-handling routined for MIPS CPUs
+ *
+ * Copyright (c) 2003 Wolfgang Denk <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
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/cacheops.h>
+
+#define RA t9
+
+/*
+ * 16kB is the maximum size of instruction and data caches on MIPS 4K,
+ * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
+ *
+ * Note that the above size is the maximum size of primary cache. U-Boot
+ * doesn't have L2 cache support for now.
+ */
+#define MIPS_MAX_CACHE_SIZE 0x10000
+
+#define INDEX_BASE CKSEG0
+
+ .macro cache_op op addr
+ .set push
+ .set noreorder
+ .set mips3
+ cache \op, 0(\addr)
+ .set pop
+ .endm
+
+ .macro f_fill64 dst, offset, val
+ LONG_S \val, (\offset + 0 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 1 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 2 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 3 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 4 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 5 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 6 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 7 * LONGSIZE)(\dst)
+#if LONGSIZE == 4
+ LONG_S \val, (\offset + 8 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 9 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 10 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 11 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 12 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 13 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 14 * LONGSIZE)(\dst)
+ LONG_S \val, (\offset + 15 * LONGSIZE)(\dst)
+#endif
+ .endm
+
+/*
+ * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
+ */
+LEAF(mips_init_icache)
+ blez a1, 9f
+ mtc0 zero, CP0_TAGLO
+ /* clear tag to invalidate */
+ PTR_LI t0, INDEX_BASE
+ PTR_ADDU t1, t0, a1
+1: cache_op INDEX_STORE_TAG_I t0
+ PTR_ADDU t0, a2
+ bne t0, t1, 1b
+ /* fill once, so data field parity is correct */
+ PTR_LI t0, INDEX_BASE
+2: cache_op FILL t0
+ PTR_ADDU t0, a2
+ bne t0, t1, 2b
+ /* invalidate again - prudent but not strictly neccessary */
+ PTR_LI t0, INDEX_BASE
+1: cache_op INDEX_STORE_TAG_I t0
+ PTR_ADDU t0, a2
+ bne t0, t1, 1b
+9: jr ra
+ END(mips_init_icache)
+
+/*
+ * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
+ */
+LEAF(mips_init_dcache)
+ blez a1, 9f
+ mtc0 zero, CP0_TAGLO
+ /* clear all tags */
+ PTR_LI t0, INDEX_BASE
+ PTR_ADDU t1, t0, a1
+1: cache_op INDEX_STORE_TAG_D t0
+ PTR_ADDU t0, a2
+ bne t0, t1, 1b
+ /* load from each line (in cached space) */
+ PTR_LI t0, INDEX_BASE
+2: LONG_L zero, 0(t0)
+ PTR_ADDU t0, a2
+ bne t0, t1, 2b
+ /* clear all tags */
+ PTR_LI t0, INDEX_BASE
+1: cache_op INDEX_STORE_TAG_D t0
+ PTR_ADDU t0, a2
+ bne t0, t1, 1b
+9: jr ra
+ END(mips_init_dcache)
+
+/*
+ * mips_cache_reset - low level initialisation of the primary caches
+ *
+ * This routine initialises the primary caches to ensure that they have good
+ * parity. It must be called by the ROM before any cached locations are used
+ * to prevent the possibility of data with bad parity being written to memory.
+ *
+ * To initialise the instruction cache it is essential that a source of data
+ * with good parity is available. This routine will initialise an area of
+ * memory starting at location zero to be used as a source of parity.
+ *
+ * RETURNS: N/A
+ *
+ */
+NESTED(mips_cache_reset, 0, ra)
+ move RA, ra
+ li t2, CONFIG_SYS_ICACHE_SIZE
+ li t3, CONFIG_SYS_DCACHE_SIZE
+ li t8, CONFIG_SYS_CACHELINE_SIZE
+
+ li v0, MIPS_MAX_CACHE_SIZE
+
+ /*
+ * Now clear that much memory starting from zero.
+ */
+ PTR_LI a0, CKSEG1
+ PTR_ADDU a1, a0, v0
+2: PTR_ADDIU a0, 64
+ f_fill64 a0, -64, zero
+ bne a0, a1, 2b
+
+ /*
+ * The caches are probably in an indeterminate state,
+ * so we force good parity into them by doing an
+ * invalidate, load/fill, invalidate for each line.
+ */
+
+ /*
+ * Assume bottom of RAM will generate good parity for the cache.
+ */
+
+ /*
+ * Initialize the I-cache first,
+ */
+ move a1, t2
+ move a2, t8
+ PTR_LA v1, mips_init_icache
+ jalr v1
+
+ /*
+ * then initialize D-cache.
+ */
+ move a1, t3
+ move a2, t8
+ PTR_LA v1, mips_init_dcache
+ jalr v1
+
+ jr RA
+ END(mips_cache_reset)
+
+/*
+ * dcache_status - get cache status
+ *
+ * RETURNS: 0 - cache disabled; 1 - cache enabled
+ *
+ */
+LEAF(dcache_status)
+ mfc0 t0, CP0_CONFIG
+ li t1, CONF_CM_UNCACHED
+ andi t0, t0, CONF_CM_CMASK
+ move v0, zero
+ beq t0, t1, 2f
+ li v0, 1
+2: jr ra
+ END(dcache_status)
+
+/*
+ * dcache_disable - disable cache
+ *
+ * RETURNS: N/A
+ *
+ */
+LEAF(dcache_disable)
+ mfc0 t0, CP0_CONFIG
+ li t1, -8
+ and t0, t0, t1
+ ori t0, t0, CONF_CM_UNCACHED
+ mtc0 t0, CP0_CONFIG
+ jr ra
+ END(dcache_disable)
+
+/*
+ * dcache_enable - enable cache
+ *
+ * RETURNS: N/A
+ *
+ */
+LEAF(dcache_enable)
+ mfc0 t0, CP0_CONFIG
+ ori t0, CONF_CM_CMASK
+ xori t0, CONF_CM_CMASK
+ ori t0, CONF_CM_CACHABLE_NONCOHERENT
+ mtc0 t0, CP0_CONFIG
+ jr ra
+ END(dcache_enable)
diff --git a/arch/mips/cpu/mips64/config.mk b/arch/mips/cpu/mips64/config.mk
new file mode 100644
index 0000000..ebc1ceb
--- /dev/null
+++ b/arch/mips/cpu/mips64/config.mk
@@ -0,0 +1,40 @@
+#
+# (C) Copyright 2003
+# Wolfgang Denk, DENX Software 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
+#
+
+#
+# Default optimization level for MIPS64
+#
+# Note: Toolchains with binutils prior to v2.16
+# are no longer supported by U-Boot MIPS tree!
+#
+MIPSFLAGS = -march=mips64
+
+PLATFORM_CPPFLAGS += $(MIPSFLAGS)
+PLATFORM_CPPFLAGS += -mabi=64 -DCONFIG_64BIT
+ifdef CONFIG_SYS_BIG_ENDIAN
+PLATFORM_LDFLAGS += -m elf64btsmip
+else
+PLATFORM_LDFLAGS += -m elf64ltsmip
+endif
+
+CONFIG_STANDALONE_LOAD_ADDR ?= 0xffffffff80200000 -T mips64.lds
diff --git a/arch/mips/cpu/mips64/cpu.c b/arch/mips/cpu/mips64/cpu.c
new file mode 100644
index 0000000..2a38d0c
--- /dev/null
+++ b/arch/mips/cpu/mips64/cpu.c
@@ -0,0 +1,111 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software 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
+ */
+
+#include <common.h>
+#include <command.h>
+#include <netdev.h>
+#include <asm/mipsregs.h>
+#include <asm/cacheops.h>
+#include <asm/reboot.h>
+
+#define cache_op(op, addr) \
+ __asm__ __volatile__( \
+ " .set push\n" \
+ " .set noreorder\n" \
+ " .set mips64\n" \
+ " cache %0, %1\n" \
+ " .set pop\n" \
+ : \
+ : "i" (op), "R" (*(unsigned char *)(addr)))
+
+void __attribute__((weak)) _machine_restart(void)
+{
+ fprintf(stderr, "*** reset failed ***\n");
+
+ while (1)
+ /* NOP */;
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ _machine_restart();
+
+ return 0;
+}
+
+void flush_cache(ulong start_addr, ulong size)
+{
+ unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
+ unsigned long addr = start_addr & ~(lsize - 1);
+ unsigned long aend = (start_addr + size - 1) & ~(lsize - 1);
+
+ /* aend will be miscalculated when size is zero, so we return here */
+ if (size == 0)
+ return;
+
+ while (1) {
+ cache_op(HIT_WRITEBACK_INV_D, addr);
+ cache_op(HIT_INVALIDATE_I, addr);
+ if (addr == aend)
+ break;
+ addr += lsize;
+ }
+}
+
+void flush_dcache_range(ulong start_addr, ulong stop)
+{
+ unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
+ unsigned long addr = start_addr & ~(lsize - 1);
+ unsigned long aend = (stop - 1) & ~(lsize - 1);
+
+ while (1) {
+ cache_op(HIT_WRITEBACK_INV_D, addr);
+ if (addr == aend)
+ break;
+ addr += lsize;
+ }
+}
+
+void invalidate_dcache_range(ulong start_addr, ulong stop)
+{
+ unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
+ unsigned long addr = start_addr & ~(lsize - 1);
+ unsigned long aend = (stop - 1) & ~(lsize - 1);
+
+ while (1) {
+ cache_op(HIT_INVALIDATE_D, addr);
+ if (addr == aend)
+ break;
+ addr += lsize;
+ }
+}
+
+void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
+{
+ write_c0_entrylo0(low0);
+ write_c0_pagemask(pagemask);
+ write_c0_entrylo1(low1);
+ write_c0_entryhi(hi);
+ write_c0_index(index);
+ tlb_write_indexed();
+}
diff --git a/arch/mips/cpu/mips64/interrupts.c b/arch/mips/cpu/mips64/interrupts.c
new file mode 100644
index 0000000..e4e9aae
--- /dev/null
+++ b/arch/mips/cpu/mips64/interrupts.c
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software 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
+ */
+
+#include <common.h>
+#include <asm/mipsregs.h>
+
+void enable_interrupts(void)
+{
+}
+
+int disable_interrupts(void)
+{
+ return 0;
+}
diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S
new file mode 100644
index 0000000..4112de7
--- /dev/null
+++ b/arch/mips/cpu/mips64/start.S
@@ -0,0 +1,256 @@
+/*
+ * Startup Code for MIPS64 CPU-core
+ *
+ * Copyright (c) 2003 Wolfgang Denk <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 dlater 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 PARTICUdlaR 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 Pdlace, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+
+#ifndef CONFIG_SYS_MIPS_CACHE_MODE
+#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
+#endif
+
+ /*
+ * For the moment disable interrupts, mark the kernel mode and
+ * set ST0_KX so that the CPU does not spit fire when using
+ * 64-bit addresses.
+ */
+ .macro setup_c0_status set clr
+ .set push
+ mfc0 t0, CP0_STATUS
+ or t0, ST0_CU0 | \set | 0x1f | \clr
+ xor t0, 0x1f | \clr
+ mtc0 t0, CP0_STATUS
+ .set noreorder
+ sll zero, 3 # ehb
+ .set pop
+ .endm
+
+ .set noreorder
+
+ .globl _start
+ .text
+_start:
+ .org 0x000
+ b reset
+ nop
+ .org 0x080
+ b romReserved
+ nop
+ .org 0x100
+ b romReserved
+ nop
+ .org 0x180
+ b romReserved
+ nop
+ .org 0x200
+ b romReserved
+ nop
+ .org 0x280
+ b romReserved
+ nop
+ .org 0x300
+ b romReserved
+ nop
+ .org 0x380
+ b romReserved
+ nop
+ .org 0x480
+ b romReserved
+ nop
+
+ /*
+ * We hope there are no more reserved vectors!
+ * 128 * 8 == 1024 == 0x400
+ * so this is address R_VEC+0x400 == 0xbfc00400
+ */
+ .org 0x500
+ .align 4
+reset:
+
+ /* Clear watch registers */
+ dmtc0 zero, CP0_WATCHLO
+ dmtc0 zero, CP0_WATCHHI
+
+ /* WP(Watch Pending), SW0/1 should be cleared */
+ mtc0 zero, CP0_CAUSE
+
+ setup_c0_status ST0_KX 0
+
+ /* Init Timer */
+ mtc0 zero, CP0_COUNT
+ mtc0 zero, CP0_COMPARE
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ /* CONFIG0 register */
+ dli t0, CONF_CM_UNCACHED
+ mtc0 t0, CP0_CONFIG
+#endif
+
+ /* Initialize $gp */
+ bal 1f
+ nop
+ .dword _gp
+1:
+ ld gp, 0(ra)
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ /* Initialize any external memory */
+ dla t9, lowlevel_init
+ jalr t9
+ nop
+
+ /* Initialize caches... */
+ dla t9, mips_cache_reset
+ jalr t9
+ nop
+
+ /* ... and enable them */
+ dli t0, CONFIG_SYS_MIPS_CACHE_MODE
+ mtc0 t0, CP0_CONFIG
+#endif
+
+ /* Set up temporary stack */
+ dli t0, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET
+ dla sp, 0(t0)
+
+ dla t9, board_init_f
+ jr t9
+ nop
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * a0 = addr_sp
+ * a1 = gd
+ * a2 = destination address
+ */
+ .globl relocate_code
+ .ent relocate_code
+relocate_code:
+ move sp, a0 # set new stack pointer
+
+ dli t0, CONFIG_SYS_MONITOR_BASE
+ dla t3, in_ram
+ ld t2, -24(t3) # t2 <-- uboot_end_data
+ move t1, a2
+ move s2, a2 # s2 <-- destination address
+
+ /*
+ * Fix $gp:
+ *
+ * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address
+ */
+ move t8, gp
+ dsub gp, CONFIG_SYS_MONITOR_BASE
+ dadd gp, a2 # gp now adjusted
+ dsub s1, gp, t8 # s1 <-- relocation offset
+
+ /*
+ * t0 = source address
+ * t1 = target address
+ * t2 = source end address
+ */
+
+ /*
+ * Save destination address and size for dlater usage in flush_cache()
+ */
+ move s0, a1 # save gd in s0
+ move a0, t1 # a0 <-- destination addr
+ dsub a1, t2, t0 # a1 <-- size
+
+1:
+ lw t3, 0(t0)
+ sw t3, 0(t1)
+ daddu t0, 4
+ ble t0, t2, 1b
+ daddu t1, 4
+
+ /* If caches were enabled, we would have to flush them here. */
+
+ /* a0 & a1 are already set up for flush_cache(start, size) */
+ dla t9, flush_cache
+ jalr t9
+ nop
+
+ /* Jump to where we've relocated ourselves */
+ daddi t0, s2, in_ram - _start
+ jr t0
+ nop
+
+ .dword _gp
+ .dword _GLOBAL_OFFSET_TABLE_
+ .dword uboot_end_data
+ .dword uboot_end
+ .dword num_got_entries
+
+in_ram:
+ /*
+ * Now we want to update GOT.
+ *
+ * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
+ * generated by GNU ld. Skip these reserved entries from relocation.
+ */
+ ld t3, -8(t0) # t3 <-- num_got_entries
+ ld t8, -32(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_
+ ld t9, -40(t0) # t9 <-- _gp
+ dsub t8, t9 # compute offset
+ dadd t8, t8, gp # t8 now holds relocated _G_O_T_
+ daddi t8, t8, 16 # skipping first two entries
+ dli t2, 2
+1:
+ ld t1, 0(t8)
+ beqz t1, 2f
+ dadd t1, s1
+ sd t1, 0(t8)
+2:
+ daddi t2, 1
+ blt t2, t3, 1b
+ daddi t8, 8
+
+ /* Clear BSS */
+ ld t1, -24(t0) # t1 <-- uboot_end_data
+ ld t2, -16(t0) # t2 <-- uboot_end
+ dadd t1, s1 # adjust pointers
+ dadd t2, s1
+
+ dsub t1, 8
+1:
+ daddi t1, 8
+ bltl t1, t2, 1b
+ sd zero, 0(t1)
+
+ move a0, s0 # a0 <-- gd
+ dla t9, board_init_r
+ jr t9
+ move a1, s2
+
+ .end relocate_code
+
+ /* Exception handlers */
+romReserved:
+ b romReserved
diff --git a/arch/mips/cpu/mips64/time.c b/arch/mips/cpu/mips64/time.c
new file mode 100644
index 0000000..5154280
--- /dev/null
+++ b/arch/mips/cpu/mips64/time.c
@@ -0,0 +1,87 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software 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
+ */
+
+#include <common.h>
+#include <asm/mipsregs.h>
+
+static unsigned long timestamp;
+
+/* how many counter cycles in a jiffy */
+#define CYCLES_PER_JIFFY \
+ (CONFIG_SYS_MIPS_TIMER_FREQ + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ
+
+/*
+ * timer without interrupts
+ */
+
+int timer_init(void)
+{
+ /* Set up the timer for the first expiration. */
+ timestamp = 0;
+ write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY);
+
+ return 0;
+}
+
+ulong get_timer(ulong base)
+{
+ unsigned int count;
+ unsigned int expirelo = read_c0_compare();
+
+ /* Check to see if we have missed any timestamps. */
+ count = read_c0_count();
+ while ((count - expirelo) < 0x7fffffff) {
+ expirelo += CYCLES_PER_JIFFY;
+ timestamp++;
+ }
+ write_c0_compare(expirelo);
+
+ return timestamp - base;
+}
+
+void __udelay(unsigned long usec)
+{
+ unsigned int tmo;
+
+ tmo = read_c0_count() + (usec * (CONFIG_SYS_MIPS_TIMER_FREQ / 1000000));
+ while ((tmo - read_c0_count()) < 0x7fffffff)
+ /*NOP*/;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On MIPS it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On MIPS it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}
diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c
index ddcbfaa..cc190df 100644
--- a/arch/mips/cpu/xburst/cpu.c
+++ b/arch/mips/cpu/xburst/cpu.c
@@ -84,8 +84,8 @@ void flush_cache(ulong start_addr, ulong size)
unsigned long aend = (start_addr + size - 1) & ~(lsize - 1);
for (; addr <= aend; addr += lsize) {
- cache_op(Hit_Writeback_Inv_D, addr);
- cache_op(Hit_Invalidate_I, addr);
+ cache_op(HIT_WRITEBACK_INV_D, addr);
+ cache_op(HIT_INVALIDATE_I, addr);
}
}
@@ -96,7 +96,7 @@ void flush_dcache_range(ulong start_addr, ulong stop)
unsigned long aend = (stop - 1) & ~(lsize - 1);
for (; addr <= aend; addr += lsize)
- cache_op(Hit_Writeback_Inv_D, addr);
+ cache_op(HIT_WRITEBACK_INV_D, addr);
}
void invalidate_dcache_range(ulong start_addr, ulong stop)
@@ -106,7 +106,7 @@ void invalidate_dcache_range(ulong start_addr, ulong stop)
unsigned long aend = (stop - 1) & ~(lsize - 1);
for (; addr <= aend; addr += lsize)
- cache_op(Hit_Invalidate_D, addr);
+ cache_op(HIT_INVALIDATE_D, addr);
}
void flush_icache_all(void)
@@ -118,7 +118,7 @@ void flush_icache_all(void)
for (addr = CKSEG0; addr < CKSEG0 + CONFIG_SYS_ICACHE_SIZE;
addr += CONFIG_SYS_CACHELINE_SIZE) {
- cache_op(Index_Store_Tag_I, addr);
+ cache_op(INDEX_STORE_TAG_I, addr);
}
/* invalidate btb */
@@ -139,7 +139,7 @@ void flush_dcache_all(void)
for (addr = CKSEG0; addr < CKSEG0 + CONFIG_SYS_DCACHE_SIZE;
addr += CONFIG_SYS_CACHELINE_SIZE) {
- cache_op(Index_Writeback_Inv_D, addr);
+ cache_op(INDEX_WRITEBACK_INV_D, addr);
}
__asm__ __volatile__("sync");
diff --git a/arch/mips/cpu/xburst/start.S b/arch/mips/cpu/xburst/start.S
index d846104..3a8280c 100644
--- a/arch/mips/cpu/xburst/start.S
+++ b/arch/mips/cpu/xburst/start.S
@@ -96,7 +96,7 @@ relocate_code:
li t0, KSEG0
addi t1, t0, CONFIG_SYS_DCACHE_SIZE
2:
- cache Index_Writeback_Inv_D, 0(t0)
+ cache INDEX_WRITEBACK_INV_D, 0(t0)
bne t0, t1, 2b
addi t0, CONFIG_SYS_CACHELINE_SIZE
@@ -106,7 +106,7 @@ relocate_code:
li t0, KSEG0
addi t1, t0, CONFIG_SYS_ICACHE_SIZE
3:
- cache Index_Invalidate_I, 0(t0)
+ cache INDEX_INVALIDATE_I, 0(t0)
bne t0, t1, 3b
addi t0, CONFIG_SYS_CACHELINE_SIZE
diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h
index 3a1e6d6..b768bb5 100644
--- a/arch/mips/include/asm/addrspace.h
+++ b/arch/mips/include/asm/addrspace.h
@@ -136,7 +136,7 @@
cannot access physical memory directly from core */
#define UNCACHED_SDRAM(a) (((unsigned long)(a)) | 0x20000000)
#else /* !CONFIG_SOC_AU1X00 */
-#define UNCACHED_SDRAM(a) KSEG1ADDR(a)
+#define UNCACHED_SDRAM(a) CKSEG1ADDR(a)
#endif /* CONFIG_SOC_AU1X00 */
#endif /* __ASSEMBLY__ */
diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h
index 608cfcf..933ccb1 100644
--- a/arch/mips/include/asm/asm.h
+++ b/arch/mips/include/asm/asm.h
@@ -401,7 +401,7 @@ symbol = value
#ifdef CONFIG_SGI_IP28
/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
#include <asm/cacheops.h>
-#define R10KCBARRIER(addr) cache Cache_Barrier, addr;
+#define R10KCBARRIER(addr) cache CACHE_BARRIER, addr;
#else
#define R10KCBARRIER(addr)
#endif
diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h
index 70bcad7..6464250 100644
--- a/arch/mips/include/asm/cacheops.h
+++ b/arch/mips/include/asm/cacheops.h
@@ -14,54 +14,54 @@
/*
* Cache Operations available on all MIPS processors with R4000-style caches
*/
-#define Index_Invalidate_I 0x00
-#define Index_Writeback_Inv_D 0x01
-#define Index_Load_Tag_I 0x04
-#define Index_Load_Tag_D 0x05
-#define Index_Store_Tag_I 0x08
-#define Index_Store_Tag_D 0x09
+#define INDEX_INVALIDATE_I 0x00
+#define INDEX_WRITEBACK_INV_D 0x01
+#define INDEX_LOAD_TAG_I 0x04
+#define INDEX_LOAD_TAG_D 0x05
+#define INDEX_STORE_TAG_I 0x08
+#define INDEX_STORE_TAG_D 0x09
#if defined(CONFIG_CPU_LOONGSON2)
-#define Hit_Invalidate_I 0x00
+#define HIT_INVALIDATE_I 0x00
#else
-#define Hit_Invalidate_I 0x10
+#define HIT_INVALIDATE_I 0x10
#endif
-#define Hit_Invalidate_D 0x11
-#define Hit_Writeback_Inv_D 0x15
+#define HIT_INVALIDATE_D 0x11
+#define HIT_WRITEBACK_INV_D 0x15
/*
* R4000-specific cacheops
*/
-#define Create_Dirty_Excl_D 0x0d
-#define Fill 0x14
-#define Hit_Writeback_I 0x18
-#define Hit_Writeback_D 0x19
+#define CREATE_DIRTY_EXCL_D 0x0d
+#define FILL 0x14
+#define HIT_WRITEBACK_I 0x18
+#define HIT_WRITEBACK_D 0x19
/*
* R4000SC and R4400SC-specific cacheops
*/
-#define Index_Invalidate_SI 0x02
-#define Index_Writeback_Inv_SD 0x03
-#define Index_Load_Tag_SI 0x06
-#define Index_Load_Tag_SD 0x07
-#define Index_Store_Tag_SI 0x0A
-#define Index_Store_Tag_SD 0x0B
-#define Create_Dirty_Excl_SD 0x0f
-#define Hit_Invalidate_SI 0x12
-#define Hit_Invalidate_SD 0x13
-#define Hit_Writeback_Inv_SD 0x17
-#define Hit_Writeback_SD 0x1b
-#define Hit_Set_Virtual_SI 0x1e
-#define Hit_Set_Virtual_SD 0x1f
+#define INDEX_INVALIDATE_SI 0x02
+#define INDEX_WRITEBACK_INV_SD 0x03
+#define INDEX_LOAD_TAG_SI 0x06
+#define INDEX_LOAD_TAG_SD 0x07
+#define INDEX_STORE_TAG_SI 0x0A
+#define INDEX_STORE_TAG_SD 0x0B
+#define CREATE_DIRTY_EXCL_SD 0x0f
+#define HIT_INVALIDATE_SI 0x12
+#define HIT_INVALIDATE_SD 0x13
+#define HIT_WRITEBACK_INV_SD 0x17
+#define HIT_WRITEBACK_SD 0x1b
+#define HIT_SET_VIRTUAL_SI 0x1e
+#define HIT_SET_VIRTUAL_SD 0x1f
/*
* R5000-specific cacheops
*/
-#define R5K_Page_Invalidate_S 0x17
+#define R5K_PAGE_INVALIDATE_S 0x17
/*
* RM7000-specific cacheops
*/
-#define Page_Invalidate_T 0x16
+#define PAGE_INVALIDATE_T 0x16
/*
* R10000-specific cacheops
@@ -69,17 +69,17 @@
* Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
* Most of the _S cacheops are identical to the R4000SC _SD cacheops.
*/
-#define Index_Writeback_Inv_S 0x03
-#define Index_Load_Tag_S 0x07
-#define Index_Store_Tag_S 0x0B
-#define Hit_Invalidate_S 0x13
-#define Cache_Barrier 0x14
-#define Hit_Writeback_Inv_S 0x17
-#define Index_Load_Data_I 0x18
-#define Index_Load_Data_D 0x19
-#define Index_Load_Data_S 0x1b
-#define Index_Store_Data_I 0x1c
-#define Index_Store_Data_D 0x1d
-#define Index_Store_Data_S 0x1f
+#define INDEX_WRITEBACK_INV_S 0x03
+#define INDEX_LOAD_TAG_S 0x07
+#define INDEX_STORE_TAG_S 0x0B
+#define HIT_INVALIDATE_S 0x13
+#define CACHE_BARRIER 0x14
+#define HIT_WRITEBACK_INV_S 0x17
+#define INDEX_LOAD_DATA_I 0x18
+#define INDEX_LOAD_DATA_D 0x19
+#define INDEX_LOAD_DATA_S 0x1b
+#define INDEX_STORE_DATA_I 0x1c
+#define INDEX_STORE_DATA_D 0x1d
+#define INDEX_STORE_DATA_S 0x1f
#endif /* __ASM_CACHEOPS_H */
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 025012a..80eab75 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -120,12 +120,20 @@ static inline void set_io_port_base(unsigned long base)
*/
extern inline phys_addr_t virt_to_phys(volatile void * address)
{
+#ifndef CONFIG_64BIT
return CPHYSADDR(address);
+#else
+ return XPHYSADDR(address);
+#endif
}
extern inline void * phys_to_virt(unsigned long address)
{
+#ifndef CONFIG_64BIT
return (void *)KSEG0ADDR(address);
+#else
+ return (void *)CKSEG0ADDR(address);
+#endif
}
/*
@@ -133,12 +141,20 @@ extern inline void * phys_to_virt(unsigned long address)
*/
extern inline unsigned long virt_to_bus(volatile void * address)
{
+#ifndef CONFIG_64BIT
return CPHYSADDR(address);
+#else
+ return XPHYSADDR(address);
+#endif
}
extern inline void * bus_to_virt(unsigned long address)
{
+#ifndef CONFIG_64BIT
return (void *)KSEG0ADDR(address);
+#else
+ return (void *)CKSEG0ADDR(address);
+#endif
}
/*
diff --git a/arch/mips/include/asm/posix_types.h b/arch/mips/include/asm/posix_types.h
index 879aae2..4deac52 100644
--- a/arch/mips/include/asm/posix_types.h
+++ b/arch/mips/include/asm/posix_types.h
@@ -24,9 +24,15 @@ typedef int __kernel_pid_t;
typedef int __kernel_ipc_pid_t;
typedef int __kernel_uid_t;
typedef int __kernel_gid_t;
+#if _MIPS_SZLONG != 64
typedef unsigned int __kernel_size_t;
typedef int __kernel_ssize_t;
typedef int __kernel_ptrdiff_t;
+#else
+typedef unsigned long __kernel_size_t;
+typedef long __kernel_ssize_t;
+typedef long __kernel_ptrdiff_t;
+#endif
typedef long __kernel_time_t;
typedef long __kernel_suseconds_t;
typedef long __kernel_clock_t;