On Fri, Aug 24, 2012 at 8:22 AM, Daniel Schwierzeck < daniel.schwierz...@gmail.com> wrote:
> 2012/8/20 Zhizhou Zhang <etou...@gmail.com>: > > These files are derived from arch/mips/cpu/mips32/*. Howerver some > > Changes are made: > > *.S: changes ABI o32 to n64 > > config.mk: add mips64 building cflags > > cpu.c: add cache size probe > > interrupts.c: implement enable_interrupts and disable_interrupts > > > > Signed-off-by: Zhizhou Zhang <etou...@gmail.com> > > --- > > arch/mips/cpu/mips64/Makefile | 47 +++++++ > > arch/mips/cpu/mips64/config.mk | 39 ++++++ > > arch/mips/cpu/mips64/cpu.c | 124 ++++++++++++++++++ > > arch/mips/cpu/mips64/interrupts.c | 39 ++++++ > > arch/mips/cpu/mips64/start.S | 256 > +++++++++++++++++++++++++++++++++++++ > > arch/mips/cpu/mips64/time.c | 86 +++++++++++++ > > 6 files changed, 591 insertions(+) > > create mode 100644 arch/mips/cpu/mips64/Makefile > > 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 > > > > diff --git a/arch/mips/cpu/mips64/Makefile > b/arch/mips/cpu/mips64/Makefile > > new file mode 100644 > > index 0000000..335fe88 > > --- /dev/null > > +++ b/arch/mips/cpu/mips64/Makefile > > @@ -0,0 +1,47 @@ > > +# > > +# (C) Copyright 2003-2006 > > +# Wolfgang Denk, DENX Software Engineering, w...@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 > > + > > +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/config.mk b/arch/mips/cpu/mips64/ > config.mk > > new file mode 100644 > > index 0000000..26f79e6 > > --- /dev/null > > +++ b/arch/mips/cpu/mips64/config.mk > > @@ -0,0 +1,39 @@ > > +# > > +# (C) Copyright 2003 > > +# Wolfgang Denk, DENX Software Engineering, <w...@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 > > + > > +ENDIANNESS = -EL > > + > > +MIPSFLAGS += $(ENDIANNESS) > > with current master branch in git://git.denx.de/u-boot-mips.git you can > drop the > endianess flags which are now handled in arch/mips/config.mk > > > + > > +PLATFORM_CPPFLAGS += $(MIPSFLAGS) > > +PLATFORM_CPPFLAGS += -mabi=64 -DCONFIG_64BIT > > +PLATFORM_LDFLAGS += -m elf64ltsmip > > + > > diff --git a/arch/mips/cpu/mips64/cpu.c b/arch/mips/cpu/mips64/cpu.c > > new file mode 100644 > > index 0000000..348ccfe > > --- /dev/null > > +++ b/arch/mips/cpu/mips64/cpu.c > > @@ -0,0 +1,124 @@ > > +/* > > + * (C) Copyright 2003 > > + * Wolfgang Denk, DENX Software Engineering, <w...@denx.de> > > + * Zhi-zhou Zhang <etou...@gmail.com> > > + * > > + * 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> > > +#include <linux/compiler.h> > > + > > +void __weak _machine_restart(void) > > +{ > > +} > > + > > +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > > +{ > > + _machine_restart(); > > + > > + fprintf(stderr, "*** reset failed ***\n"); > > + return 0; > > +} > > + > > +static struct cache_desc icache, dcache; > > + > > +void cache_probe(void) > > +{ > > + int config, lsize; > > + > > + config = read_c0_config1(); > > + lsize = (config >> 19) & 7; > > + if (lsize) { /* icache present */ > > + icache.linesz = 2 << lsize; > > + icache.sets = 32 << (((config >> 22) + 1) & 7); > > + icache.ways = 1 + ((config >> 16) & 7); > > + icache.size = icache.sets * > > + icache.ways * > > + icache.linesz; > > + } > > + > > + lsize = (config >> 10) & 7; > > + if (lsize) { /* dcache present */ > > + dcache.linesz = 2 << lsize; > > + dcache.sets = 32 << (((config >> 13) + 1) & 7); > > + dcache.ways = 1 + ((config >> 7) & 7); > > + dcache.size = dcache.sets * > > + dcache.ways * > > + dcache.linesz; > > + } > > +} > > + > > +void flush_cache(ulong start_addr, ulong size) > > +{ > > + unsigned long addr, aend; > > + > > + /* aend will be miscalculated when size is zero, so we return > here */ > > + if (size == 0) > > + return; > > + > > + addr = start_addr & ~(icache.linesz - 1); > > + aend = (start_addr + size - 1) & ~(icache.linesz - 1); > > + while (1) { > > + cache_op(Hit_Invalidate_I, addr); > > + if (addr == aend) > > + break; > > + addr += icache.linesz; > > + } > > + > > + addr = start_addr & ~(dcache.linesz - 1); > > + aend = (start_addr + size - 1) & ~(dcache.linesz - 1); > > + while (1) { > > + cache_op(Hit_Writeback_Inv_D, addr); > > + if (addr == aend) > > + break; > > + addr += dcache.linesz; > > + } > > +} > > + > > +void flush_dcache_range(ulong start_addr, ulong stop) > > +{ > > + unsigned long addr = start_addr & ~(dcache.linesz - 1); > > + unsigned long aend = (stop - 1) & ~(dcache.linesz - 1); > > + > > + while (1) { > > + cache_op(Hit_Writeback_Inv_D, addr); > > + if (addr == aend) > > + break; > > + addr += dcache.linesz; > > + } > > +} > > + > > +void invalidate_dcache_range(ulong start_addr, ulong stop) > > +{ > > + unsigned long addr = start_addr & ~(dcache.linesz - 1); > > + unsigned long aend = (stop - 1) & ~(dcache.linesz - 1); > > + > > + while (1) { > > + cache_op(Hit_Invalidate_D, addr); > > + if (addr == aend) > > + break; > > + addr += dcache.linesz; > > + } > > +} > > diff --git a/arch/mips/cpu/mips64/interrupts.c > b/arch/mips/cpu/mips64/interrupts.c > > new file mode 100644 > > index 0000000..f661fb0 > > --- /dev/null > > +++ b/arch/mips/cpu/mips64/interrupts.c > > @@ -0,0 +1,39 @@ > > +/* > > + * (C) Copyright 2003 > > + * Wolfgang Denk, DENX Software Engineering, <w...@denx.de> > > + * Zhi-zhou Zhang <etou...@gmail.com> > > + * > > + * 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 status = read_c0_status(); > > + write_c0_status(status | ST0_IE); > > +} > > + > > +int disable_interrupts(void) > > +{ > > + int status = read_c0_status(); > > + write_c0_status(status & ~ST0_IE); > > + return status | ST0_IE; > > +} > > currently we cannot use interrupts or setup any interrupt handlers in > u-boot-mips. > Please leave those functions empty. > > > diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S > > new file mode 100644 > > index 0000000..b8585e7 > > --- /dev/null > > +++ b/arch/mips/cpu/mips64/start.S > > @@ -0,0 +1,256 @@ > > +/* > > + * Startup Code for MIPS64 CPU-core > > + * > > + * Copyright (c) 2003 Wolfgang Denk <w...@denx.de> > > + * Copyright (c) 2012 Zhi-zhou Zhang <etou...@gmail.com> > > + * > > + * 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) > > + > > + dla t9, cache_probe > > + jalr t9 > > + nop > > calling a C function is not supposed to work here because no stack > pointer has been setup yet. > I checked with Sourcery 2011.09 and 2012.03. The stack is always > utilized in cache_probe. > Either you rewrite the cache_probe function in assembler or you use > the existing config options > and you could drop the cache probing. > > Thanks, So could I put it in board/qemu-mips/qemu-mips.c? I think when power on, all cache are in invalid state, we don't need flush it at all. So only if we do cache_probe before calling flush opertaions, everything goes ok. am i right? > > + > > +#ifndef CONFIG_SKIP_LOWLEVEL_INIT > > + /* Initialize any external memory */ > > + dla t9, lowlevel_init > > + 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..350896a > > --- /dev/null > > +++ b/arch/mips/cpu/mips64/time.c > > @@ -0,0 +1,86 @@ > > +/* > > + * (C) Copyright 2003 > > + * Wolfgang Denk, DENX Software Engineering, w...@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; > > +} > > -- > > 1.7.9.5 > > > > > > -- > Best regards, > Daniel > -- Regards, Zhizhou Zhang
_______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot