--- /dev/null Thu Jan 6 02:10:11 2011 +++ linux-2.6.36/arch/mips/boot/compressed/invcache.S Thu Jan 6 01:32:57 2011 @@ -0,0 +1,132 @@ +/*- + * written 2011 by Thorsten Glaser based on + * code from LZMA-Loader with the following copyright note: + * Copyright 2005 Oleg I. Vdovikin + * cache manipulation adapted from Broadcom code + * idea taken from original bunzip2 decompressor code + * Copyright 2004 Manuel Novoa III + */ + +/* + * This file is supposed to be #include’d where it’s + * needed; we will not trash s0, s1, s2, s3. + */ + +#define KSEG0 0x80000000 + +#define C0_CONFIG $16 +#define C0_TAGLO $28 +#define C0_TAGHI $29 + +#define CONF1_DA_SHIFT 7 /* D$ associativity */ +#define CONF1_DA_MASK 0x00000380 +#define CONF1_DA_BASE 1 +#define CONF1_DL_SHIFT 10 /* D$ line size */ +#define CONF1_DL_MASK 0x00001c00 +#define CONF1_DL_BASE 2 +#define CONF1_DS_SHIFT 13 /* D$ sets/way */ +#define CONF1_DS_MASK 0x0000e000 +#define CONF1_DS_BASE 64 +#define CONF1_IA_SHIFT 16 /* I$ associativity */ +#define CONF1_IA_MASK 0x00070000 +#define CONF1_IA_BASE 1 +#define CONF1_IL_SHIFT 19 /* I$ line size */ +#define CONF1_IL_MASK 0x00380000 +#define CONF1_IL_BASE 2 +#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ +#define CONF1_IS_MASK 0x01c00000 +#define CONF1_IS_BASE 64 + +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 + + /* Get cache sizes */ + .set mips32 + mfc0 s4,C0_CONFIG,1 + .set mips0 + + li s5,CONF1_DL_MASK + and s5,s4 + beq s5,zero,2f + nop + + srl s5,CONF1_DL_SHIFT + li t0,CONF1_DL_BASE + sll s5,t0,s5 /* s5 has D$ cache line size */ + + li s6,CONF1_DA_MASK + and s6,s4 + srl s6,CONF1_DA_SHIFT + addiu s6,CONF1_DA_BASE /* s6 now has D$ associativity */ + + li t0,CONF1_DS_MASK + and t0,s4 + srl t0,CONF1_DS_SHIFT + li s7,CONF1_DS_BASE + sll s7,s7,t0 /* s7 has D$ sets per way */ + + multu s6,s7 /* sets/way * associativity */ + mflo t0 /* total cache lines */ + + multu s5,t0 /* D$ linesize * lines */ + mflo s6 /* s6 is now D$ size in bytes */ + + /* Initilize the D$: */ + mtc0 zero,C0_TAGLO + mtc0 zero,C0_TAGHI + + li t0,KSEG0 /* Just an address for the first $ line */ + addu t1,t0,s6 /* + size of cache == end */ + + .set mips3 +1: cache Index_Writeback_Inv_D,0(t0) + .set mips0 + bne t0,t1,1b + addu t0,s5 + +2: + /* Now we get to do it all again for the I$ */ + + move s7,zero /* just in case there is no icache */ + move t8,zero + + li t0,CONF1_IL_MASK + and t0,s4 + beq t0,zero,3f + nop + + srl t0,CONF1_IL_SHIFT + li s7,CONF1_IL_BASE + sll s7,t0 /* s7 has I$ cache line size */ + + li t0,CONF1_IA_MASK + and t0,s4 + srl t0,CONF1_IA_SHIFT + addiu t8,t0,CONF1_IA_BASE /* t8 now has I$ associativity */ + + li t0,CONF1_IS_MASK + and t0,s4 + srl t0,CONF1_IS_SHIFT + li t9,CONF1_IS_BASE + sll t9,t0 /* t9 has I$ sets per way */ + + multu t8,t9 /* sets/way * associativity */ + mflo t0 /* t8 is now total cache lines */ + + multu s7,t0 /* I$ linesize * lines */ + mflo t8 /* t8 is cache size in bytes */ + + /* Initilize the I$: */ + mtc0 zero,C0_TAGLO + mtc0 zero,C0_TAGHI + + li t0,KSEG0 /* Just an address for the first $ line */ + addu t1,t0,t8 /* + size of cache == end */ + + .set mips3 +1: cache Index_Invalidate_I,0(t0) + .set mips0 + bne t0,t1,1b + addu t0,s7 + +3: --- /dev/null Thu Jan 6 00:14:18 2011 +++ linux-2.6.36/arch/mips/boot/compressed/selfreloc.lds.S Wed Jan 5 23:52:43 2011 @@ -0,0 +1,39 @@ +/*- + * written 2010 by Thorsten Glaser based on + * arch/mips/kernel/vmlinux.lds and arch/mips/boot/compressed/ld.script + */ + +#include +#include +#include + +#undef mips +#define mips mips +OUTPUT_ARCH(mips) +ENTRY(selfreloc_start) +PHDRS { + text PT_LOAD FLAGS(7); /* RWX */ +} +SECTIONS +{ + . = VMLINUX_LOAD_ADDRESS; + .text : { + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + *(.data) + *(.data.*) + *(.bss) + *(.bss.*) + } :text + /DISCARD/ : { + *(.MIPS.options) + *(.options) + *(.pdr) + *(.reginfo) + *(.comment) + *(.note) + *(.gnu.attributes) + } +} --- /dev/null Thu Jan 6 02:10:14 2011 +++ linux-2.6.36/arch/mips/boot/compressed/selfreloc.S Thu Jan 6 01:21:44 2011 @@ -0,0 +1,60 @@ +/*- + * written 2011 by Thorsten Glaser based on + * arch/mips/boot/compressed/head.S and code from LZMA-Loader + */ + +#include +#include + + .set noreorder + .cprestore + + .text + LEAF(selfreloc_start) +selfreloc_start: + /* Save boot rom start args */ + move s0, a0 + move s1, a1 + move s2, a2 + move s3, a3 + + /* Copy code to the correct place */ + PTR_LI a0, VMLINUZ_LOAD_ADDRESS + PTR_LA a1, imgbeg + PTR_LA a2, imgend +1: lw t0, 0(a1) + sw t0, 0(a0) + add a1, 4 + add a0, 4 + blt a1, a2, 1b + nop + + /* + * At this point we need to invalidate dcache and + * icache before jumping to the new code + */ +/* #include "invcache.S" // since this may work only on brcm? */ + + /* Restore boot rom start args */ + move a0, s0 + move a1, s1 + move a2, s2 + move a3, s3 + + /* Jump to the code at its new location */ + PTR_LI k0, VMLINUZ_LOAD_ADDRESS + jr k0 + nop + + /* Just in case we come back… */ +3: + b 3b + nop + END(selfreloc_start) + + .globl imgbeg + .p2align 2 +imgbeg: .incbin "vmlinuz.bin" + .globl imgend + .p2align 2 +imgend: --- linux-2.6.36/arch/mips/boot/compressed/Makefile~ Wed Jan 5 21:26:40 2011 +++ linux-2.6.36/arch/mips/boot/compressed/Makefile Wed Jan 5 23:35:58 2011 @@ -62,8 +62,13 @@ $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vm # Calculate the load address of the compressed kernel image hostprogs-y := calc_vmlinuz_load_addr +ifdef CONFIG_BCM47XX +# XXX just after CFE, just pray the address is static +VMLINUZ_LOAD_ADDRESS = 0xffffffff80480000 +else VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \ $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS)) +endif vmlinuzobjs-y += $(obj)/piggy.o @@ -106,4 +107,12 @@ OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFL vmlinuz.srec: vmlinuz $(call cmd,objcopy) -clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec} +AFLAGS_selfreloc.o := -DVMLINUZ_LOAD_ADDRESS=$(VMLINUZ_LOAD_ADDRESS) +arch/mips/boot/compressed/selfreloc.o: arch/mips/boot/compressed/selfreloc.S vmlinuz.bin arch/mips/boot/compressed/invcache.S + +CPPFLAGS_selfreloc.lds := $(KBUILD_CFLAGS) + +vmlinub.elf: arch/mips/boot/compressed/selfreloc.o arch/mips/boot/compressed/selfreloc.lds + $(LD) $(LDFLAGS) -T arch/mips/boot/compressed/selfreloc.lds arch/mips/boot/compressed/selfreloc.o -o $@ + +clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec} $(objtree)/vmlinub.elf $(objtree)/arch/mips/boot/compressed/selfreloc.{o,lds} --- linux-2.6.36/arch/mips/Makefile~ Wed Jan 5 20:26:12 2011 +++ linux-2.6.36/arch/mips/Makefile Wed Jan 5 22:41:38 2011 @@ -79,6 +79,7 @@ endif all-$(CONFIG_BOOT_ELF32) := $(vmlinux-32) all-$(CONFIG_BOOT_ELF64) := $(vmlinux-64) all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz +all-$(CONFIG_BCM47XX) += vmlinub.elf # # GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel @@ -285,7 +286,7 @@ vmlinux.bin vmlinux.ecoff vmlinux.srec: $(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) arch/mips/boot/$@ # boot/compressed -vmlinuz vmlinuz.bin vmlinuz.ecoff vmlinuz.srec: $(vmlinux-32) FORCE +vmlinuz vmlinuz.bin vmlinuz.ecoff vmlinuz.srec vmlinub.elf: $(vmlinux-32) FORCE $(Q)$(MAKE) $(build)=arch/mips/boot/compressed \ VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $@ @@ -322,6 +323,7 @@ define archhelp echo ' vmlinuz.ecoff - ECOFF zboot image' echo ' vmlinuz.bin - Raw binary zboot image' echo ' vmlinuz.srec - SREC zboot image' + echo ' vmlinub.elf - ELF self-relocating zboot image' echo echo ' These will be default as apropriate for a configured platform.' endef