diff mbox

[U-Boot,V4,1/4] MIPS: Add support for MIPS64 cpus

Message ID 1346071750-6634-7-git-send-email-etou.zh@gmail.com
State Superseded
Delegated to: Daniel Schwierzeck
Headers show

Commit Message

Zhi-zhou Zhang Aug. 27, 2012, 12:49 p.m. UTC
These files are derived from arch/mips/cpu/mips32/*. The main changes are:
1, changes ABI o32 to n64, 2, add mips64 build cflags.

Signed-off-by: Zhizhou Zhang <etou.zh@gmail.com>
---
 arch/mips/cpu/mips64/Makefile     |   46 +++++++
 arch/mips/cpu/mips64/cache.S      |  229 +++++++++++++++++++++++++++++++++
 arch/mips/cpu/mips64/config.mk    |   40 ++++++
 arch/mips/cpu/mips64/cpu.c        |  111 ++++++++++++++++
 arch/mips/cpu/mips64/interrupts.c |   34 +++++
 arch/mips/cpu/mips64/start.S      |  256 +++++++++++++++++++++++++++++++++++++
 arch/mips/cpu/mips64/time.c       |   87 +++++++++++++
 7 files changed, 803 insertions(+)
 create mode 100644 arch/mips/cpu/mips64/Makefile
 create mode 100644 arch/mips/cpu/mips64/cache.S
 create mode 100644 arch/mips/cpu/mips64/config.mk
 create mode 100644 arch/mips/cpu/mips64/cpu.c
 create mode 100644 arch/mips/cpu/mips64/interrupts.c
 create mode 100644 arch/mips/cpu/mips64/start.S
 create mode 100644 arch/mips/cpu/mips64/time.c

Comments

Wolfgang Denk Sept. 1, 2012, 12:42 p.m. UTC | #1
Dear Zhizhou Zhang,

In message <1346071750-6634-7-git-send-email-etou.zh@gmail.com> you wrote:
> These files are derived from arch/mips/cpu/mips32/*. The main changes are:
> 1, changes ABI o32 to n64, 2, add mips64 build cflags.
> 
> Signed-off-by: Zhizhou Zhang <etou.zh@gmail.com>

Checkpatch reports a number of "unnecessary whitespace before a quoted
newline" warnings; please fix these.

> diff --git a/arch/mips/cpu/mips64/Makefile b/arch/mips/cpu/mips64/Makefile
> new file mode 100644
> index 0000000..f4c88f5
> --- /dev/null
> +++ b/arch/mips/cpu/mips64/Makefile
...
> +sinclude $(obj).depend
> +
> diff --git a/arch/mips/cpu/mips64/cache.S b/arch/mips/cpu/mips64/cache.S

Please do not add trailing empty lines.  Please fix globally.

...
> +++ b/arch/mips/cpu/mips64/config.mk
> @@ -0,0 +1,40 @@
...
> +CONFIG_STANDALONE_LOAD_ADDR ?= 0xFfffFfff80200000 -T mips64.lds

As requested before: please don't mix upper and lower case letters in
a number; use a consistent styile everywhere. PLease fix globally.


As requested before: please make sure your patches are bisectable.
This references file mips64.lds, but doesn;t add it, so it cannot
work.

...
> +#define cache_op(op, addr)						\
> +	__asm__ __volatile__(						\
> +	"	.set	push					\n"	\
> +	"	.set	noreorder				\n"	\
> +	"	.set	mips64\n\t				\n"	\
> +	"	cache	%0, %1					\n"	\
> +	"	.set	pop					\n"	\

Fix checkpatch warnings here (and globally).

> +	while (1) {
> +		cache_op(Hit_Writeback_Inv_D, addr);
> +		cache_op(Hit_Invalidate_I, addr);

We don't allow camel-case identifiers.  Please fix globally.



Best regards,

Wolfgang Denk
Zhi-zhou Zhang Sept. 2, 2012, 1:56 p.m. UTC | #2
Dear Wolfgang Denk,

On Sat, Sep 1, 2012 at 8:42 PM, Wolfgang Denk <wd@denx.de> wrote:

> Dear Zhizhou Zhang,
>
> In message <1346071750-6634-7-git-send-email-etou.zh@gmail.com> you wrote:
> > These files are derived from arch/mips/cpu/mips32/*. The main changes
> are:
> > 1, changes ABI o32 to n64, 2, add mips64 build cflags.
> >
> > Signed-off-by: Zhizhou Zhang <etou.zh@gmail.com>
>
> Checkpatch reports a number of "unnecessary whitespace before a quoted
> newline" warnings; please fix these.
>
> > diff --git a/arch/mips/cpu/mips64/Makefile
> b/arch/mips/cpu/mips64/Makefile
> > new file mode 100644
> > index 0000000..f4c88f5
> > --- /dev/null
> > +++ b/arch/mips/cpu/mips64/Makefile
> ...
> > +sinclude $(obj).depend
> > +
> > diff --git a/arch/mips/cpu/mips64/cache.S b/arch/mips/cpu/mips64/cache.S
>
> Please do not add trailing empty lines.  Please fix globally.
>
> ...
> > +++ b/arch/mips/cpu/mips64/config.mk
> > @@ -0,0 +1,40 @@
> ...
> > +CONFIG_STANDALONE_LOAD_ADDR ?= 0xFfffFfff80200000 -T mips64.lds
>
> As requested before: please don't mix upper and lower case letters in
> a number; use a consistent styile everywhere. PLease fix globally.
>
>
> As requested before: please make sure your patches are bisectable.
> This references file mips64.lds, but doesn;t add it, so it cannot
> work.
>
I'm a new learner, Please forgive my faults. So do you mean that we should
can build
u-boot on each submit? If it is, should I resend these patch?

>

...
> > +#define cache_op(op, addr)                                           \
> > +     __asm__ __volatile__(                                           \
> > +     "       .set    push                                    \n"     \
> > +     "       .set    noreorder                               \n"     \
> > +     "       .set    mips64\n\t                              \n"     \
> > +     "       cache   %0, %1                                  \n"     \
> > +     "       .set    pop                                     \n"     \
>
> Fix checkpatch warnings here (and globally).
>
> > +     while (1) {
> > +             cache_op(Hit_Writeback_Inv_D, addr);
> > +             cache_op(Hit_Invalidate_I, addr);
>
> We don't allow camel-case identifiers.  Please fix globally.
>
> I thought these identifiers come from Linux Kernel and mips spec.
I will fix it as you command

>
>
> Best regards,
>
> Wolfgang Denk
>
> --
> DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
> If it has syntax, it isn't user friendly.
>
Wolfgang Denk Sept. 2, 2012, 2:14 p.m. UTC | #3
Dear Zhi-zhou Zhang,

In message <CACFOYQmTwH-7SwnS_QgPcXMCZovbXhkJPJhJnFi92zXcZazVug@mail.gmail.com> you wrote:
>
> > As requested before: please make sure your patches are bisectable.
> > This references file mips64.lds, but doesn;t add it, so it cannot
> > work.
> >
> I'm a new learner, Please forgive my faults. So do you mean that we should can build
> u-boot on each submit? If it is, should I resend these patch?

When running "git bisect", any commit may be selected for building, so
it is essential that the code is at least compile clean for all
commits.  That means for example that you cannot add files in a later
commit, because then any earlier commits which try to reference these
would cause build errors.

Your patches need to be reorganized to make sure of this.

Best regards,

Wolfgang Denk
Daniel Schwierzeck Sept. 4, 2012, 10:20 p.m. UTC | #4
Dear Wolfgang,

2012/9/1 Wolfgang Denk <wd@denx.de>:
> Dear Zhizhou Zhang,
>
> In message <1346071750-6634-7-git-send-email-etou.zh@gmail.com> you wrote:
[...]
>
>> +     while (1) {
>> +             cache_op(Hit_Writeback_Inv_D, addr);
>> +             cache_op(Hit_Invalidate_I, addr);
>
> We don't allow camel-case identifiers.  Please fix globally.
>

those identifiers are from arch/mips/include/asm/cacheops.h which is
imported from Linux like many other header files in U-Boot.
Does it really make sense to fix the coding style of imported files?

According to http://www.denx.de/wiki/U-Boot/CodingStyle you allow exceptions:
"Source files originating from different projects (for example the MTD
subsystem or the hush shell code from the BusyBox project) may,
after careful consideration, be exempted from these rules. For such
files, the original coding style may be kept to ease subsequent
migration to newer versions of those sources. "
diff mbox

Patch

diff --git a/arch/mips/cpu/mips64/Makefile b/arch/mips/cpu/mips64/Makefile
new file mode 100644
index 0000000..f4c88f5
--- /dev/null
+++ b/arch/mips/cpu/mips64/Makefile
@@ -0,0 +1,46 @@ 
+#
+# (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..ba7c1b8
--- /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..4fe6ea0
--- /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..c890e15
--- /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\t				\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..dc941b8
--- /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 */
+	li	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 */
+	li	t0, CONFIG_SYS_MIPS_CACHE_MODE
+	mtc0	t0, CP0_CONFIG
+#endif
+
+	/* Set up temporary stack */
+	li	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
+
+	li	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
+	li	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;
+}