]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
MIPS: add board qemu-mips64 support
authorZhi-zhou Zhang <etou.zh@gmail.com>
Tue, 16 Oct 2012 13:02:08 +0000 (15:02 +0200)
committerDaniel Schwierzeck <daniel.schwierzeck@gmail.com>
Tue, 16 Oct 2012 13:02:08 +0000 (15:02 +0200)
Both big-endian and little-endian are tested with below commands:
Rom version: (Default, Now we config it as rom version)
qemu-system-mips64el -M mips -bios u-boot.bin -cpu MIPS64R2-generic -nographic
qemu-system-mips64 -M mips -bios u-boot.bin -cpu MIPS64R2-generic -nographic
Ram version:
qemu-system-mips64el -M mips -cpu MIPS64R2-generic -kernel u-boot -nographic
qemu-system-mips64 -M mips -cpu MIPS64R2-generic -kernel u-boot -nographic

Signed-off-by: Zhizhou Zhang <etou.zh@gmail.com>
Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
arch/mips/cpu/mips64/Makefile [new file with mode: 0644]
arch/mips/cpu/mips64/cache.S [new file with mode: 0644]
arch/mips/cpu/mips64/config.mk [new file with mode: 0644]
arch/mips/cpu/mips64/cpu.c [new file with mode: 0644]
arch/mips/cpu/mips64/interrupts.c [new file with mode: 0644]
arch/mips/cpu/mips64/start.S [new file with mode: 0644]
arch/mips/cpu/mips64/time.c [new file with mode: 0644]
board/qemu-mips/u-boot.lds
boards.cfg
examples/standalone/mips64.lds [new file with mode: 0644]
include/configs/qemu-mips64.h [new file with mode: 0644]

diff --git a/arch/mips/cpu/mips64/Makefile b/arch/mips/cpu/mips64/Makefile
new file mode 100644 (file)
index 0000000..be38664
--- /dev/null
@@ -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 (file)
index 0000000..036f035
--- /dev/null
@@ -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 (file)
index 0000000..ebc1ceb
--- /dev/null
@@ -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 (file)
index 0000000..2a38d0c
--- /dev/null
@@ -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 (file)
index 0000000..e4e9aae
--- /dev/null
@@ -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 (file)
index 0000000..4112de7
--- /dev/null
@@ -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 (file)
index 0000000..5154280
--- /dev/null
@@ -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;
+}
index 9460b2010cc6f5643a336220bd42c9df3ac19f03..4d9580f817448cc239373c3a27855c2c25c54fa9 100644 (file)
 /*
 OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-bigmips")
 */
+#if defined(CONFIG_64BIT)
+OUTPUT_FORMAT("elf64-tradbigmips", "elf64-tradbigmips", "elf64-tradlittlemips")
+#else
 OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
+#endif
 OUTPUT_ARCH(mips)
 ENTRY(_start)
 SECTIONS
@@ -63,7 +67,11 @@ SECTIONS
        }
 
        uboot_end_data = .;
+#if defined(CONFIG_64BIT)
+       num_got_entries = (__got_end - __got_start) >> 3;
+#else
        num_got_entries = (__got_end - __got_start) >> 2;
+#endif
 
        . = ALIGN(4);
        .sbss  : { *(.sbss*) }
index 4b17289722e42b1f510e90ab36c97649552b2d18..cbfba73c33ff95dfa6bb45ed82bdd0e6a1877c68 100644 (file)
@@ -404,6 +404,8 @@ M5485HFE                 m68k        mcf547x_8x  m548xevb            freescale      -
 microblaze-generic           microblaze  microblaze  microblaze-generic  xilinx
 qemu_mips                    mips        mips32      qemu-mips           -              -           qemu-mips:SYS_BIG_ENDIAN
 qemu_mipsel                  mips        mips32      qemu-mips           -              -           qemu-mips:SYS_LITTLE_ENDIAN
+qemu_mips64                  mips        mips64      qemu-mips           -              -           qemu-mips64:SYS_BIG_ENDIAN
+qemu_mips64el                mips        mips64      qemu-mips           -              -           qemu-mips64:SYS_LITTLE_ENDIAN
 vct_platinum                 mips        mips32      vct                 micronas       -           vct:VCT_PLATINUM
 vct_platinumavc              mips        mips32      vct                 micronas       -           vct:VCT_PLATINUMAVC
 vct_platinumavc_onenand      mips        mips32      vct                 micronas       -           vct:VCT_PLATINUMAVC,VCT_ONENAND
diff --git a/examples/standalone/mips64.lds b/examples/standalone/mips64.lds
new file mode 100644 (file)
index 0000000..9b27ef4
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * (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("elf64-tradbigmips", "elf64-tradbigmips", "elf64-tradlittlemips")
+OUTPUT_ARCH(mips)
+SECTIONS
+{
+       .text       :
+       {
+         *(.text*)
+       }
+
+       . = ALIGN(4);
+       .rodata  : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+       . = ALIGN(4);
+       .data  : { *(.data*) }
+
+       . = .;
+       _gp = ALIGN(16) + 0x7ff0;
+
+       .got : {
+         __got_start = .;
+         *(.got)
+         __got_end = .;
+       }
+
+       .sdata  : { *(.sdata*) }
+
+       . = ALIGN(4);
+       __bss_start = .;
+       .sbss (NOLOAD) : { *(.sbss*) }
+       .bss (NOLOAD)  : { *(.bss*) . = ALIGN(4); }
+
+       _end = .;
+}
diff --git a/include/configs/qemu-mips64.h b/include/configs/qemu-mips64.h
new file mode 100644 (file)
index 0000000..82647e2
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * (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
+ */
+
+/*
+ * This file contains the configuration parameters for qemu-mips64 target.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_MIPS64                  /* MIPS64 CPU core */
+#define CONFIG_QEMU_MIPS
+#define CONFIG_MISC_INIT_R
+
+#define CONFIG_BOOTDELAY       10      /* autoboot after 10 seconds */
+
+#define CONFIG_BAUDRATE                115200
+
+#define CONFIG_TIMESTAMP               /* Print image info with timestamp */
+#undef CONFIG_BOOTARGS
+
+#define CONFIG_EXTRA_ENV_SETTINGS                                      \
+       "addmisc=setenv bootargs ${bootargs} "                          \
+               "console=ttyS0,${baudrate} "                            \
+               "panic=1\0"                                             \
+       "bootfile=/tftpboot/vmlinux\0"                                  \
+       "load=tftp ffffffff80500000 ${u-boot}\0"                        \
+       ""
+
+#define CONFIG_BOOTCOMMAND     "bootp;bootelf"
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+
+/*
+ * Command line configuration.
+ */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+#undef CONFIG_CMD_LOADB
+#undef CONFIG_CMD_LOADS
+#define CONFIG_CMD_DHCP
+
+#define CONFIG_DRIVER_NE2000
+#define CONFIG_DRIVER_NE2000_BASE      0xffffffffb4000300
+
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE    1
+#define CONFIG_SYS_NS16550_CLK         115200
+#define CONFIG_SYS_NS16550_COM1                0xffffffffb40003f8
+#define CONFIG_CONS_INDEX              1
+
+#define CONFIG_CMD_IDE
+#define CONFIG_DOS_PARTITION
+
+#define CONFIG_SYS_IDE_MAXBUS          2
+#define CONFIG_SYS_ATA_IDE0_OFFSET     0x1f0
+#define CONFIG_SYS_ATA_IDE1_OFFSET     0x170
+#define CONFIG_SYS_ATA_DATA_OFFSET     0
+#define CONFIG_SYS_ATA_REG_OFFSET      0
+#define CONFIG_SYS_ATA_BASE_ADDR       0xffffffffb4000000
+
+#define CONFIG_SYS_IDE_MAXDEVICE       4
+
+#define CONFIG_CMD_RARP
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP            /* undef to save memory */
+
+/* Monitor Command Prompt */
+#if defined(CONFIG_SYS_LITTLE_ENDIAN)
+#define CONFIG_SYS_PROMPT              "qemu-mips64el # "
+#else
+#define CONFIG_SYS_PROMPT              "qemu-mips64 # "
+#endif
+
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_HUSH_PARSER
+
+/* Console I/O Buffer Size */
+#define CONFIG_SYS_CBSIZE              256
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)
+/* max number of command args */
+#define CONFIG_SYS_MAXARGS             16
+
+#define CONFIG_SYS_MALLOC_LEN          128*1024
+
+#define CONFIG_SYS_BOOTPARAMS_LEN      128*1024
+
+#define CONFIG_SYS_MHZ                 132
+
+#define CONFIG_SYS_MIPS_TIMER_FREQ     (CONFIG_SYS_MHZ * 1000000)
+
+#define CONFIG_SYS_HZ                  1000
+
+/* Cached addr */
+#define CONFIG_SYS_SDRAM_BASE          0xffffffff80000000
+
+/* default load address */
+#define CONFIG_SYS_LOAD_ADDR           0xffffffff81000000
+
+#define CONFIG_SYS_MEMTEST_START       0xffffffff80100000
+#define CONFIG_SYS_MEMTEST_END         0xffffffff80800000
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+/* The following #defines are needed to get flash environment right */
+#define CONFIG_SYS_TEXT_BASE           0xffffffffbfc00000 /* Rom version */
+#define CONFIG_SYS_MONITOR_BASE        CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_MONITOR_LEN         (192 << 10)
+
+#define CONFIG_SYS_INIT_SP_OFFSET      0x400000
+
+/* We boot from this flash, selected with dip switch */
+#define CONFIG_SYS_FLASH_BASE          0xffffffffbfc00000
+#define CONFIG_SYS_MAX_FLASH_BANKS     1
+#define CONFIG_SYS_MAX_FLASH_SECT      128
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_FLASH_CFI_DRIVER
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+
+#define CONFIG_ENV_IS_IN_FLASH
+#define CONFIG_ENV_ADDR                (CONFIG_SYS_FLASH_BASE + CONFIG_SYS_MONITOR_LEN)
+
+/* Address and size of Primary Environment Sector */
+#define CONFIG_ENV_SIZE                0x8000
+
+#define CONFIG_ENV_OVERWRITE   1
+
+#define MEM_SIZE               128
+
+#define CONFIG_LZMA
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CONFIG_SYS_DCACHE_SIZE         16384
+#define CONFIG_SYS_ICACHE_SIZE         16384
+#define CONFIG_SYS_CACHELINE_SIZE      32
+
+#endif /* __CONFIG_H */