diff options
| author | Zhi-zhou Zhang <etou.zh@gmail.com> | 2012-10-16 15:02:08 +0200 | 
|---|---|---|
| committer | Daniel Schwierzeck <daniel.schwierzeck@gmail.com> | 2012-10-16 15:02:08 +0200 | 
| commit | 32afad783eb5a372c276fcb9fb30dfb838615909 (patch) | |
| tree | 814d29b73e53e414ad1b80f752d2566de4715aeb | |
| parent | ff9b0cb8b4804ed372c09b8aad2a984b396596b2 (diff) | |
| download | olio-uboot-2014.01-32afad783eb5a372c276fcb9fb30dfb838615909.tar.xz olio-uboot-2014.01-32afad783eb5a372c276fcb9fb30dfb838615909.zip | |
MIPS: add board qemu-mips64 support
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>
| -rw-r--r-- | arch/mips/cpu/mips64/Makefile | 45 | ||||
| -rw-r--r-- | arch/mips/cpu/mips64/cache.S | 229 | ||||
| -rw-r--r-- | arch/mips/cpu/mips64/config.mk | 40 | ||||
| -rw-r--r-- | arch/mips/cpu/mips64/cpu.c | 111 | ||||
| -rw-r--r-- | arch/mips/cpu/mips64/interrupts.c | 34 | ||||
| -rw-r--r-- | arch/mips/cpu/mips64/start.S | 256 | ||||
| -rw-r--r-- | arch/mips/cpu/mips64/time.c | 87 | ||||
| -rw-r--r-- | board/qemu-mips/u-boot.lds | 8 | ||||
| -rw-r--r-- | boards.cfg | 2 | ||||
| -rw-r--r-- | examples/standalone/mips64.lds | 59 | ||||
| -rw-r--r-- | include/configs/qemu-mips64.h | 175 | 
11 files changed, 1046 insertions, 0 deletions
| diff --git a/arch/mips/cpu/mips64/Makefile b/arch/mips/cpu/mips64/Makefile new file mode 100644 index 000000000..be3866484 --- /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 000000000..036f035d9 --- /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 000000000..ebc1ceb83 --- /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 000000000..2a38d0c8d --- /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 000000000..e4e9aae0c --- /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 000000000..4112de702 --- /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 000000000..51542808d --- /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/board/qemu-mips/u-boot.lds b/board/qemu-mips/u-boot.lds index 9460b2010..4d9580f81 100644 --- a/board/qemu-mips/u-boot.lds +++ b/board/qemu-mips/u-boot.lds @@ -24,7 +24,11 @@  /*  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*) } diff --git a/boards.cfg b/boards.cfg index 4b1728972..cbfba73c3 100644 --- a/boards.cfg +++ b/boards.cfg @@ -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 index 000000000..9b27ef476 --- /dev/null +++ b/examples/standalone/mips64.lds @@ -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 index 000000000..82647e2b1 --- /dev/null +++ b/include/configs/qemu-mips64.h @@ -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 */ |