1/* 2 * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards 3 * 4 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> 5 * 6 * Some parts of this code was based on the OpenWrt specific lzma-loader 7 * for the BCM47xx and ADM5120 based boards: 8 * Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) 9 * Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License version 2 as published 13 * by the Free Software Foundation. 14 */ 15 16#include <asm/asm.h> 17#include <asm/regdef.h> 18#include "cp0regdef.h" 19#include "cacheops.h" 20#include "config.h" 21 22#define KSEG0 0x80000000 23 24 .macro ehb 25 sll zero, 3 26 .endm 27 28 .text 29 30LEAF(startup) 31 .set noreorder 32 .set mips32 33 34 mtc0 zero, CP0_WATCHLO # clear watch registers 35 mtc0 zero, CP0_WATCHHI 36 mtc0 zero, CP0_CAUSE # clear before writing status register 37 38 mfc0 t0, CP0_STATUS 39 li t1, 0x1000001f 40 or t0, t1 41 xori t0, 0x1f 42 mtc0 t0, CP0_STATUS 43 ehb 44 45 mtc0 zero, CP0_COUNT 46 mtc0 zero, CP0_COMPARE 47 ehb 48 49 la t0, __reloc_label # get linked address of label 50 bal __reloc_label # branch and link to label to 51 nop # get actual address 52__reloc_label: 53 subu t0, ra, t0 # get reloc_delta 54 55 beqz t0, __reloc_done # if delta is 0 we are in the right place 56 nop 57 58 /* Copy our code to the right place */ 59 la t1, _code_start # get linked address of _code_start 60 la t2, _code_end # get linked address of _code_end 61 addu t0, t0, t1 # calculate actual address of _code_start 62 63__reloc_copy: 64 lw t3, 0(t0) 65 sw t3, 0(t1) 66 add t1, 4 67 blt t1, t2, __reloc_copy 68 add t0, 4 69 70 /* flush cache */ 71 la t0, _code_start 72 la t1, _code_end 73 74 li t2, ~(CONFIG_CACHELINE_SIZE - 1) 75 and t0, t2 76 and t1, t2 77 li t2, CONFIG_CACHELINE_SIZE 78 79 b __flush_check 80 nop 81 82__flush_line: 83 cache Hit_Writeback_Inv_D, 0(t0) 84 cache Hit_Invalidate_I, 0(t0) 85 add t0, t2 86 87__flush_check: 88 bne t0, t1, __flush_line 89 nop 90 91 sync 92 93__reloc_done: 94 95 /* clear bss */ 96 la t0, _bss_start 97 la t1, _bss_end 98 b __bss_check 99 nop 100 101__bss_fill: 102 sw zero, 0(t0) 103 addi t0, 4 104 105__bss_check: 106 bne t0, t1, __bss_fill 107 nop 108 109 /* Setup new "C" stack */ 110 la sp, _stack 111 112 /* reserve stack space for a0-a3 registers */ 113 subu sp, 16 114 115 /* jump to the decompressor routine */ 116 la t0, loader_main 117 jr t0 118 nop 119 120 .set reorder 121END(startup) 122